NS3学习--dynamic-global-routing

一、学习工具:

   1.  参考资源:

        a.《ns-3网络模拟器基础及应用》

        b. NS-3中文手册

        c. NS3官网 https://www.nsnam.org/ ,下载ns-3 manual/ns-3 tutorial,

            在线ns-3 doxygen查找需要的函数跳转.  https://www.nsnam.org/docs/release/3.29/doxygen/

    2.  代码阅读撰写:

        a. Windows下使用 source insight阅读,编写代码可以自动补全以及提示错误;

        b. Linux下使用 eclipse进行代码阅读,debug调试等;

        c. 两者结合使用效果更佳。

二、学习内容:NS3目录下/examples/routing/dynamic-global-routing.cc

    1.  代码实现内容(可查看本文件注释,解释的很详细):

        该动态路由实现了点对点(point-to-point)和csma信道传输,在特定时间传输UDP数据流,并设置节点ipv4接口的开关来实现动态计算路由。

        a. 拓扑结构如下:


NS3学习--dynamic-global-routing_第1张图片

        b. 事件顺序:

        1s-16s 第一个CBR/UDP数据流从n1-n6,10s-16s第二个CBR/UDP数据流从n1-n6;在准备阶段,会预先计算全局路由,n1-n6的点对点最短路径;

        1s:第一个n1-n6的数据流开启;

        2s:n1节点关闭down,n1-n6链路断开,n1和n6重新计算路径,n1-n2-n5-n6;

        4s:n1节点打开up,n1-n6链路重新连接,n1和n6重新计算路径,n1-n6;

        6s:n6节点关闭down,n1-n6链路断开,n1和n6重新计算路径,n1-n2-n5-n6;

        8s:n6节点打开up,n1-n6链路重新连接,n1和n6重新计算路径,n1-n6;

        10s:第一个数据流停止传输;

        11s:第二个数据流开始传输;

        12s:n1节点关闭down,n1-n6链路断开,n1和n6重新计算路径,n1-n2-n5-n6;

        14s:n1节点打开up,n1-n6链路重新连接,n1和n6重新计算路径,n1-n6;

        16s:第二个数据流停止传输。

      2. 代码详解,主函数部分

//设置全局路由能够根据接口状态触发全局路由重新计算,默认值为假,即关闭,在这里需要设置为真开启。

Config::SetDefault("ns3::Ipv4GlobalRouting::RespondToInterfaceEvents", BooleanValue(true));

//日志,创建节点。

 NS_LOG_INFO("Create nodes.");

//使用NodeContainer 类创建七个节点,节点编号从0开始。

//点对点信道的两个节点组成一个节点容器,本例中,csma信道的四个节点还会组成一个节点容器,一共五个容器。

 NodeContainer c;

 c.Create (7);

 NodeContainer n0n2= NodeContainer (c.Get (0), c.Get (2));

 NodeContainer n1n2= NodeContainer (c.Get (1), c.Get (2));

 NodeContainer n5n6= NodeContainer (c.Get (5), c.Get (6));

 NodeContainer n1n6= NodeContainer (c.Get (1), c.Get (6));

 NodeContainern2345 = NodeContainer (c.Get (2), c.Get (3), c.Get (4), c.Get (5));

//为创建的每个节点安装协议栈,InternetStackHelper类会为每个节点安装一个网络协议栈,主要是IP层。

InternetStackHelper internet;

internet.Install (c);

//日志,创建信道

NS_LOG_INFO ("Create channels.");

//使用PointToPointHelper类帮助创建p2p信道,即类+信道名称。

PointToPointHelper p2p;

//调用PointToPointHelper类中的设置设备属性函数SetDeviceAttribute 设置数据传输速率为5Mbps(这里的数据传输速率我个人认为应该是带宽吧..),调用设置信道属性函数SetChannelAttribute设置信道传输时延为2ms(参考ns3.PointToPointHelper.h)。

p2p.SetDeviceAttribute ("DataRate", StringValue("5Mbps"));

p2p.SetChannelAttribute ("Delay", StringValue("2ms"));

//应用PointToPointHelper类中的NetDeviceContainer Install (NodeContainer c);函数将以上设置的属性应用于节点和信道中,并将对应节点和信道放入NetDeviceContainer,即对应的一个信道的两个节点设置对应的NetDevice,然后放入容器中。

NetDeviceContainer d0d2 = p2p.Install (n0n2);

//csma信道同理,调用CsmaHelper类进行相应设置操作。

CsmaHelper csma;

csma.SetChannelAttribute ("DataRate",StringValue ("5Mbps"));

csma.SetChannelAttribute ("Delay", StringValue("2ms"));

NetDeviceContainer d2345 = csma.Install (n2345);

//设置IP地址

 NS_LOG_INFO("Assign IP Addresses.");

//调用 Ipv4AddressHelper类分配地址,唯一用户可见的API是通过设置基IP地址和子网掩码分配完成的,如下从10.1.1.0开始以子网掩码为

255.255.255.0分配地址,地址默认是从1开始单调增长。

 Ipv4AddressHelperipv4;

 ipv4.SetBase("10.1.1.0", "255.255.255.0");

//然后为上述设置的NetDevice容器中的每个节点设置一个地址,如下,节点n0对应的设备d0的ip地址为10.1.1.1,节点n2对应的设备d2的ip地址为10.1.1.2,若还有其他设备依次按照顺序分配地址。

//完整函数为Ipv4InterfaceContainer中的Ipv4AddressHelper::Assign

(const NetDeviceContainer &c),使用Ipv4接口容器对象将一个IP地址同一个设备关联起来。

//每个NetDevice都有一个关联的IPv4接口,一个ipv4接口可以有一个或者与之相关的ipv4地址。

 ipv4.Assign(d0d2);

 ipv4.SetBase("10.1.3.0", "255.255.255.0");

 Ipv4InterfaceContaineri5i6 = ipv4.Assign (d5d6);

//调用Ipv4GlobalRoutingHelper类中的PopulateRoutingTables

()成员函数,主要是建立路由数据库然后对仿真中的所有节点初始化路由表,让仿真中所有节点都会带有一个路由器。

 Ipv4GlobalRoutingHelper::PopulateRoutingTables();

/*在ipv4-global-routing-helper.cc文件中对PopulateRoutingTables

()函数定义如下,实则是调用建立全局路由数据库和初始化路由表的函数。

void

Ipv4GlobalRoutingHelper::PopulateRoutingTables (void)

{

 GlobalRouteManager::BuildGlobalRoutingDatabase ();

 GlobalRouteManager::InitializeRoutes ();

}

*/

//日志,开始创建应用,

NS_LOG_INFO ("Create Applications.");

//指定端口

uint16_t port = 9;  // Discard port (RFC 863)

//应用 OnOffHelper类中的OnOffHelper (std::string protocol, Address address); 函数帮助创建数据流

//参考inetsocketaddress.h中 InetSocketAddress (Ipv4Address ipv4, uint16_t

port);

    函数得到OnOffHelper上述函数中的地址参数Address

/*参考ipv4-interferce-container.cc中如下函数得到,i5i6对应的ipv4接口容器中第一个接口(0代表i5,1代表n6节点的接口)的ipv4地址

Ipv4Address

Ipv4InterfaceContainer::GetAddress (uint32_t i, uint32_tj) const

*/

OnOffHelper onoff ("ns3::UdpSocketFactory",

                    InetSocketAddress (i5i6.GetAddress (1), port));

//设置应用属性,即这里的UDP数据流,数据传输速率和数据包大小。还可以设置其他属性,包括开关时间等。

onoff.SetConstantRate (DataRate ("2kbps"));

onoff.SetAttribute ("PacketSize", UintegerValue(50));

onoff2.SetAttribute ("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));

onoff2.SetAttribute ("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));

//为节点设置应用并一起放置与ApplicationContainer这个容器中,参考on-off-helper.h中原型函数:

ApplicationContainer Install (Ptr node)

const;这里应该是使用了c++中的隐式转换,

利用NodeContainer中的Get()函数得到节点指针,这里是为节点1设置application应用。

//然后设置开始时间,结束时间。

ApplicationContainer apps = onoff.Install (c.Get (1));

apps.Start (Seconds (1.0));

apps.Stop (Seconds (10.0));

//利用packetsinkhelper帮助创建一个用于接收数据的对象,原函数为packet-sink-helper.h中的:

PacketSinkHelper (std::string protocol, Address address);

//Ipv4Address::GetAny (),返回值为0.0.0.0

//在创建的applicationcontainer应用容器中,将接收数据对象绑定在节点n6上,意味着n6在1s-10s接收网络中的数据。

PacketSinkHelper sink ("ns3::UdpSocketFactory",

                        Address (InetSocketAddress (Ipv4Address::GetAny (), port)));

apps = sink.Install (c.Get (6));

apps.Start (Seconds (1.0));

apps.Stop (Seconds (10.0));

//对节点n1设置接口开关,先从nodecontainer获取节点转化为指针n1

Ptr n1

= c.Get (1);

//inline

Ptr GetObject (void) const;将参数转化为一个指针

Ptr

ipv41 = n1->GetObject ();

uint32_t

ipv4ifIndex1 = 2;

//Simulator::Schedule (Time const &delay, const

Ptr &event),设置事件,包括发生时间和事件类型,

//原型函数参考simulator.h中函数:staticEventId Schedule (Time const &delay, MEM mem_ptr, OBJ obj, T1 a1);

// MEM mem_ptr成员方法指针,OBJ obj应用成员方法的对象指针,T1 a1调用的对象。

//这里是对n1节点的接口设置开关状态

Simulator::Schedule (Seconds(2),&Ipv4::SetDown,ipv41, ipv4ifIndex1);

Simulator::Schedule (Seconds (4),&Ipv4::SetUp,ipv41,ipv4ifIndex1);

//该部分就是计算计算路由,生成路由表等,关于路由下次详细解释。

Ipv4GlobalRoutingHelper g;

Ptr routingStream =Create ("dynamic-global-routing.routes",std::ios::out);

g.PrintRoutingTableAllAt (Seconds (12), routingStream);

//设置仿真参数,代码主函数完成。

NS_LOG_INFO ("Run Simulation.");

Simulator::Run ();

Simulator::Destroy ();

NS_LOG_INFO ("Done.");

你可能感兴趣的:(NS3学习--dynamic-global-routing)