ns-3 官方链接:https://www.nsnam.org/wiki/Installation
学习书目参考:《开源网络模拟器ns-3 : 架构与实践》 / 周迪之编著
如有侵权,请联系删除。
1,案例学习——点对点有线网络脚本
1.1 头文件
(1)每个模块的API被都被统一存放在“-module.h”中,可在build/ns3目录下(编译后)找到这些头文件
(2)具体的头文件介绍
#include "ns3/core-module.h" //core模块,定义了ns-3的核心功能(如模拟事件,事件调度)
#include "ns3/network-module.h" //network模块,基本的网络组件(如网络结点,分组和地址等)
#include "ns3/internet-module.h" //internet模块,定义了TCP/IP协议栈
#include "ns3/point-to-point-module.h" //point-to-point模块,
#include "ns3/applications-module.h" //application模块,定义了应用层的分组收发模型(如贪婪模型、ON/OFF模型等)
1.2 注意点:
(1)名字空间:using namespace ns3;
(2)Log系统:
NS_LOG_COMPONENT-DEFINE(''FirstScriptExample'');
这条代码的作用是,允许在该脚本中使用Log系统中的宏定义打印辅助信息,如可以打印调试信息的NS_LOG_DEBUG宏以及错误信息的NS_LOG_ERROR宏等
(3)mian()中的准备操作,如读取命令行参数,设置最小模拟时间单元、开启Log组件
CommandLine cmd;
cmd.Parse (argc, argv); //读取命令行参数
Time::SetResolution (Time::NS); //最小时间单元:ms
//打印指定Log组件信息
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
1.3 创建网络拓扑
(1)在ns3中,抽象网络拓扑原件为C++类
- 结点:Node
- 信道:Channel。(主要负责物理层协议)
- 结点中链接信道的网络设备:NetDevice。(主要负责实现链路层协议)
在first脚本中:
点对点信道:
对应的网络设备类是: PiontToPointNetDevice
信道类是:PointToPointChannel
(2)构建结点结构和网络拓扑的步骤:
- 创建结点:使用NodeContainer类,一次创建多个Node对象
- 配置信道属性:仅配置了信道属性,并非真正的创建信道对象,ns3中助手类和属性两个重要的概念,助手类屏蔽了很多实现的细节
- 创建信道并连接结点:PiontToPointHelper::Install()函数内部分别创建了两个PPP网络设备对象(PointToPointNetDevice)和一个PPP信道对象(PointToPointChannel)。两个网络设备对象被分别安装在两个结点,然后共同连接至同一信道对象。Install()函数返回一个网络设备容器NetDeviceContainer对象,其包含了为NodeContainer中所有结点所分配的NetDevice对象。如:nodes.Get(0)结点中的网络设备是devices.Get(0).
现已完成结点和信道组成的网络拓扑。即两个结点可以通过物理层和链路层通信了。但需要运行上层应用程序。
NodeContainer nodes;
nodes.Create (2); //创建网络结点
PointToPointHelper pointToPoint; //PPP信道助手类
//配置信道属性
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); //传输速率属性
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); //传播延迟属性
NetDeviceContainer devices; //创建网络设备
devices = pointToPoint.Install (nodes); //连接结点与信道
1.4 安装TCP/IP协议族
上层协议其实指的是TCP/IP协议族,ns-3中的TCP/IP协议族主要包括传输层的TCP和UDP,网络层的IP(IPv4与IPv6),ICMP(ICMPv4与ICMPv6)和一系列的路由协议。
(1) 为结点安装TCP/IP协议栈的助手类是InternetStackHelper.
InternetStackHelper stack;
stack.Install (nodes); //为node容器中的结点安装TCP/IP协议栈
(2)安装了TCP/IP协议栈的结点还不能直接通信,还需要为结点的网络设备分配IP地址。
利用Ipv4AddressHelper(分配IPv4地址)或Ipv6AddressHelper(分配Ipv6地址)。
Ipv4AddressHelper address; //为网络设备分配IP地址
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign (devices);
注解:助手类Ipv4addressHelper以10.1.1.0为起始地址、以255.255.255.0为网络掩码,分别向两个主机分配了10.1.1.1和10.1.1.2两个IP地址。
注图:IpL4Protocol是传输层UDP和TCP的基类。Ipv4是网络层IPv4协议的基类(IPv6协议的基类是Ipv6)。链路层基类为NetDevice。物理层基类是Channel。为网络设备NetDevice分配的IPv4地址保存在Ipv4Interface对象中。
重点:一个结点可以安装多个NetDevice(如同时拥有LTE和Wi-Fi网络设备的多模块移动终端),连接到多个Channel,且拥有多个IP地址。
每个结点从物理层到传输层,分别安装了PPP和TCP/IP协议族。两个结点可以运行各种基于TCP/IP的应用进行通信了。
1.5 安装应用程序
(1)ns-3对物理世界中应用程序内部网络通信功能进行了抽象,即模拟分组的发送及接收行为。ns-3应用层协议对应的C++类是Application。
(2)不同的子类定义了不同的分组收发行为:如:BulkSendApplication使用了贪婪分组发送模型。OnOffApplication使用了ON/OFF分组发送模型。
(3)在first脚本中,使用了ns3中叫UdpEcho的应用程序。
UdpEchoServerHelper echoServer (9); //监听9号端口
//在结点1中安装服务端程序
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
//配置客户端程序属性
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
//在结点0中安装客户端程序
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
注解:上述代码中,服务器端口助手UdpEchoServerHelper在结点1中创建了一个服务器端应用echoServer。echoServer自模拟启动后1.0s开始监听并接收9号端口的数据。同样,客户端助手类UdpEchoClientHelper在结点0中创建了一个客户端应用echoClient。echoClient在模拟启动后2.0s向结点1的9号端口发送一个1024B的UDP数据包,echoSever从9号端口接收到数据包后向echoClient返回一个相同大小的UDP数据包。两个应用均在模拟启动后10.0s停止。
“MaxPackets”,“Interval”,"PacketSize"是UdpEchoClient类的3个属性,分别是最大发送分组个数,分组发送间隔和分组负载字节大小。
ns-3的TCP/IP协议族的确提供了Berkeley套接字的主要API.这些API的调用都被封装在了两个应用的助手类中。UdpEchoServerHelper实际上调用了UDP的bind(),RecvFrom()和sendTo()来监听,接收和发送UDP分组。UdpEchoClientHelper则通过调用bind()和connect()来建立与服务器端的UDP连接。
与结点和网络设备容器类似,这里的应用也使用了应用容器。serverApps容器保存着结点容器nodes中所有结点上安装的Application对象。
1.6 数据生成
属性配置和数据生成,一个输入一个输出,是ns3脚本中两个非常重要的操作。
1.7 启动与结束
Simulator::Run ();
Simulator::Destroy ();
return 0;
注解:**Run()**函数执行前面定义的所有操作,完成之后,Destroy()函数执行清除操作。ns3是一个基于离散事件的模拟器。
运行结果:
larry@larry-VirtualBox:~/ns-3-allinone/ns-3.28$ ./waf --run first
Waf: Entering directory `/home/larry/ns-3-allinone/ns-3.28/build'
Waf: Leaving directory `/home/larry/ns-3-allinone/ns-3.28/build'
Build commands will be stored in build/compile_commands.json
'build' finished successfully (2.172s)
At time 2s client sent 1024 bytes to 10.1.1.2 port 9
At time 2.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 2.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 2.00737s client received 1024 bytes from 10.1.1.2 port 9
注解:0.00369s 为结点0到结点1的传输延迟和传播延迟的总和。
在PPP信道的传播延迟为0.002s; 结点0的传输延迟计算过程如下:
注解:总的单向延迟是0.00369s,1054是1024B负载,20B IPv4分组头,8B UDP分组和2B PPP分组头的大小总和。
小结:ns-3模拟脚本,可分为:网络拓扑搭建,结点协议栈安装和应用程序设置三大部分,是对结点(node类),信道(channel类),网络设备(NetDevice类)和应用(Application)这4个核心抽象概念的操作。
此外,还有助手类,存储容器,属性等技术的使用。