初识脚本:NS3 点对点有线网络:first脚本

NS3 点对点有线网络:first脚本

选取来自于ns-3官方提供的一个名为first的C++模拟脚本(examples/tutorial/first.cc)。脚本创建了一个包含两个结点的有限网络。其链路层使用点对点协议(Point-To-PointProtocol,PPP)传输分组。
关于分组(packet)在不同的协议层有不同的叫法。一般习惯把传输层分组称为报文(segment),把网络层分组称为数据报(datagram),吧链路层分组称为帧(frame)。
初识脚本:NS3 点对点有线网络:first脚本_第1张图片

1.头文件

ns-3是一个由不同的模块组成的程序库。模拟脚本通过各个模块提供的API进行网络模拟。而每个模块的API都被统一存放在"<模块名>-module.h"中。小伙伴可以在build/ns3目录下(编译后)找到这些头文件。
core模块和network模块头文件是所有脚本必须包括的。它们分别定义了ns-3的核心功能(如模拟事件、事件调度等)和基本网络组件(如网络组件、分组和地址等)。

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"

2.名字空间

整个ns-3源代码都受“ns3”名字空间保护。这样可以将ns-3项目和非ns-3项目隔离,起到很好的保护作用,也便于与其他项目整合。因此每个脚本的开始都需要声明名字空间。在ns-3中使用标准库函数时需要添加std名字空间,如"std::cout" "std::min()"等。

using namespace ns3;

3.NS_LOG_COMPONET_DEFINE

下面这行代码的作用是允许脚本中使用Log系统中的宏打印辅助信息,如打印调试信息的NS_LOG_DEBUG宏和打印错误信息的NS_LOG_ERROR宏等

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

4.main()函数中的准备工作

下面代码中所示的读取命名行参数,设置最小模拟时间单元、开启Log组件等。

  CommandLine cmd;
  cmd.Parse (argc, argv);//读取命名行参数
  
  Time::SetResolution (Time::NS); //最小时间单元:ms 
  //打印指定Log组件信息
  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

5.创建网络拓扑

在ns-3结点和信道分别抽象为Node、Channel以及结点中连接信道的网络设备NetDevice类这3个C++。不同类型对应这不同的NetDevice和Channel子类。first.cc网络设置类是PointToPointNetDevice,信道类是PointToPointChannel。初识脚本:NS3 点对点有线网络:first脚本_第2张图片

  NodeContainer nodes;
  nodes.Create (2);//创建网络结点

  PointToPointHelper pointToPoint;//PPP信道助手类
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));//传输速率属性
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));//传播延迟属性

  NetDeviceContainer devices;//创建网络设备
  devices = pointToPoint.Install (nodes);//连接结点与信道

6.安装TCP/IP协议族

为结点安装TCP/IP协议栈的助手类InternetStackHelper。

  InternetStackHelper stack;
  stack.Install (nodes);//为nodes容器中的结点安装TCP/IP协议栈

安装TCP/IP协议栈的结点还不能直接通信,还需要为结点的网络设备分配IP地址。在firstc.cc脚本中,这部分操作是通过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地址。

7.安装应用程序

ns-3模拟分组的发送和接收行为。例如,BulkSendApplication使用贪婪分组发送模型。OnOffApplication使用了ON/OFF分组发送模型。first.cc脚本选择了ns-3的一种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号端口的数据。同样,客户端助手类UdpEchoServerHelper在结点0中创建了一个客户端应用echoClient。echoClient在模拟启动2.0s向结点1的9号端口发送一个1024B的UDP数据包。echoServer从9号端口接收数据包向echoClient返回一个相同大小的UDP数据包。两个应用均在模拟启动10.0s停止。

8.数据生成

产生数据的网络模拟的一个必备的功能,属性配置和数据生成,一个输入一个输出,是ns-3脚本中两个非常重要的组成部分。由于是first模拟脚本并未涉及数据生成操作。这里不做介绍

9. 启动与结束

  Simulator::Run ();
  Simulator::Destroy ();
  return 0;

将examples/tutorial/first.cc复制到scratch文件中。运行sudo ./waf --run scratch/first
初识脚本:NS3 点对点有线网络:first脚本_第3张图片
输出信息正确的显示UdpEcho应用行为:2s,结点0(10.1.1.1)发送了一个大小为1024B的数据包给结点1(10.1.1.2)。经过0.00369s,结点1成功收到数据包返回一个相同大小的回执数据包。为什么是0.00369s。这里的时延为传输时延+传播时延。传输时延=分组大小\传输速率=1058*8/5000000=0.00169s,总的单向延迟是0.00369。1054是1024负载、20B IPV4分组头、8B UDP分组头、2B ppp分组头的大小总和。

这里是引用开源网络模拟器ns-3 架构与实践,书中讲解了NS-3的很多细节东西,适合初学者学习。https://baike.baidu.com/reference/23361050/7b71xiWZq2W1kvmFUs8TIfG5MT_F2qn-Z_Xly_fYgoqdf5z3cXXwlX6KCWgl80xCVLOJ47eruNbnJTvM0QrvHK7mh-QIRg
同时致谢我的小伙伴,一起共同学习乐观的LiShan

你可能感兴趣的:(初识ns-3)