NS-3源码学习(一)

发布时间 2023-11-13 20:52:43作者: PolarisZg

NS-3源码学习(一)

NS-3项目的源码包装的非常严密,对于仿真来说仅需要使用helper函数即可完成环境的配置。但是这种封装简直是解析ns-3数据传输的过程的一座大山。想要用传统的单步调试的方案去观察数据的流向更是寄,各种回调函数满天飞。没办法,只能从源码入手,一点点褪下这层helper函数外衣。

写本篇笔记的时候本人仅研究了ns-3中最简单的传输模型:PointToPoint的mac层的传输情况。研究层次如此的浅薄一是因为我是因为要研究802.11协议而去学习ns-3,802.11协议仅涉及mac层和phy层的设计;二是就研究了一天,让我去看更复杂的模型我也看不懂。

环境配置:

本篇笔记使用的ns-3版本号为ns-3.40,系统为安装在vmware虚拟机中的Ubuntu22.04.3LTS,研究的代码为ns-allinone-3.40/ns-3.40/examples/tutorial/first.cc文件,

  1. 将该文件拷贝至ns-allinone-3.40/ns-3.40/scratch/路径下

  2. 打开文件,控制台运行./ns3即可编译/scratch路径下的文件

  3. 使用./ns3 show targets即可查看已经编译成功的文件

  4. 使用./ns3 run <name>即可运行相应的仿真文件

源码解析

当前我们使用的互联网五层模型的结构如下,并与first.cc文件的代码相对应

img

代码中,PointToPointHelper的作用仅有:

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));

NetDeviceContainer devices;
devices = pointToPoint.Install(nodes);

也就是调整链路速率,以及构建链路层的网络;剩余代码仅需要对NetDeviceContainer操作即可。

使用F12查看Install方法的内容,可以了解到其流程为:

img

剔除掉PointToPointHelper pointToPoint后代码如下:

ObjectFactory queueFactory;
queueFactory.SetTypeId("ns3::DropTailQueue<Packet>");
ObjectFactory channelFactory;
channelFactory.SetTypeId("ns3::PointToPointChannel");
channelFactory.Set("Delay", StringValue("2ms"));
ObjectFactory deviceFactory;
deviceFactory.SetTypeId("ns3::PointToPointNetDevice");
deviceFactory.Set("DataRate", StringValue("5Mbps"));
Ptr<PointToPointNetDevice> device1 = deviceFactory.Create<PointToPointNetDevice>();
device1->SetAddress(Mac48Address::Allocate());
nodes.Get(0)->AddDevice(device1);
Ptr<Queue<Packet>> queue1 = queueFactory.Create<Queue<Packet>>();
device1->SetQueue(queue1);
Ptr<PointToPointNetDevice> device2 = deviceFactory.Create<PointToPointNetDevice>();
device2->SetAddress(Mac48Address::Allocate());
nodes.Get(1)->AddDevice(device2);
Ptr<Queue<Packet>> queue2 = queueFactory.Create<Queue<Packet>>();
device2->SetQueue(queue2);
Ptr<PointToPointChannel> channel = channelFactory.Create<PointToPointChannel>();
device1->Attach(channel);
device2->Attach(channel);

NetDeviceContainer devices;
devices.Add(device1);
devices.Add(device2);