Intro
BG:
ns-3网络仿真工具是一个用于搭建网络拓扑,测试网络算法、模拟不同环境的网络性能的一套软件,这套软件由多个小模块构成(wifi ipv4之类的模块),运行时调用哪个就编译链接哪个。(这一段是我的理解)
NS2(Network Simulator, version 2)是一种面向对象的网络仿真器,本质上是一个离散事件模拟器。由UC Berkeley开发而成。它本身有一个虚拟时钟,所有的仿真都由离散事件驱动的。(这一段是百度百科)
ns-3提供了不少用于学习的小工程,都在ns-3.xx/example下,其中最基础的就是ns-3.xx/examples/tutorial中。tutorial,教程,顾名思义就是最基础的一些实例,看了就对ns-3的大致流程有了一定认知。
目前网上的一些解析,更多都是对大段的代码进行注释,且对网络拓扑没有详细分析,而本文将对third脚本进行代码全注释以及网络拓扑详细分析。
本文主要对third.cc脚本的内容进行解析,达到记录所学,帮助更多“入坑”ns-3的小伙伴,尤其是小白,更快入门的目的。
Method
阅读源码,参考周迪之所著的《开源网络模拟器ns-3 - 架构与实践》,阅读html对module和function的说明。
Result
书接上回,https://blog.csdn.net/Mr_liu_666/article/details/121625416这篇part1归纳了third脚本的网络拓扑以及helper的基础用法,本篇博客将讲述STA和AP相互移动的移动模型以及多个有MAC和PHY的网络设备的TCPIP和应用层协议装载。
先看移动性相关代码:
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinX", DoubleValue (0.0),
"DeltaX", DoubleValue (5.0),
"DeltaY", DoubleValue (10.0),
"GridWidth", UintegerValue (3),
"LayoutType", StringValue ("RowFirst"));
//移动模型所在的头文件 "position-allocator.h"
//GridPositionAllocator 移动目标的移动空间是横纵交叉的网格,STA能移动的范围就是网格的一个个点
//MinX MinY,移动目标的起始点
//DeltaX DeltaY,格子横纵宽度,换言之横着走和纵着走走一步能走多远
//GridWidth格子宽度,就是每一行最多几个移动目标
//LayoutType 放置移动目标的时候,先放置横向的
这一段结束之后只是简单的搭建了一个如下图所示的坐标系,规定了横纵的最小刻度,规定了移动开始的起点 在哪里以及一行几个节点。更加具体的,就是待移动的点从0 0 开始移动,横着每次走5,纵着每次走10,横着每行最多3个待移动的点,移动为横向优先移动。
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
//设置移动模型,选中100*100的区域,移动目标只能在这个范围做二维的随机游走
mobility.Install (wifiStaNodes);//所有的STA节点都是上述区域随机游走
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");//设置移动模型为静止的,移动目标静止不动
mobility.Install (wifiApNode);//移动目标为AP,唯一的AP静止不动
这一段结束之后,在上一张图描述的坐标系中规定了一个横纵坐标+50 -50的界限,STA将在此界限内随机游走,AP则在0 0点保持不动。
接下来给WIFI节点、P2P节点和csma节点添加上层协议:
stack.Install (csmaNodes);//给csmaNodes(目前csmaNodes里面已经有MAC和PHY协议了(csmaDevices),且node已经连接信道了)安装TCP/IP协议栈
stack.Install (wifiApNode);//给wifiApNode(目前wifiApNode里面已经有MAC和PHY协议了
//(apDevices,分为mac和phy两部分),且node已经连接信道了(channel))安装TCP/IP协议栈
stack.Install (wifiStaNodes);//给wifiStaNodes(目前wifiStaNodes里面已经有MAC和PHY协议了
//(staDevices,分为mac和phy两部分),且node已经连接信道了(channel))安装TCP/IP协议栈
//移动性与上层协议、底层协议都无关,是单独的
//有的朋友就会好奇啦,p2pNodes去哪了——p2pNodes(0)就是wifiApNode,p2pNodes(1)在csmaNodes里面包含着,换言之,p2pNodes这两个节点都有“双重身份”,也就有双份的顶层协议
协议中的IP协议需要给每一个节点都分配IP地址,参考ns-3.35_third.cc_ns-3网络仿真工具wifi脚本解析_wifi脚本网络拓扑_ns-3third脚本全注释_基础ns-3_ns-3入门_ns-3third脚本解析_Part1_Mr_liu_666的博客-CSDN博客https://blog.csdn.net/Mr_liu_666/article/details/121625416?spm=1001.2014.3001.5502中的图可以知道p2p节点总共有两个,这两个节点同一个直接是AP节点,一个是普通的p2p节点,但是通过csma有线信道连接了若干csma节点——如果对应实物的话,就是一个路由器(AP+p2p)无线连着很多设备(STA),有线(p2p)连着一个p2p设备,同这个p2p设备连接到一个csma交换机上,同时这个交换机上还有多个其他csma设备。安装了协议栈之后我的拓扑图如下:
有了TCP(UDP)/IP协议之后,每个节点都需要一个自己的IP地址,通过省时省力的helper给节点分配地址,单网卡单地址,双网卡双地址。
Ipv4AddressHelper address;//给各个节点的每一个网络设备配置IP地址
address.SetBase ("10.1.1.0", "255.255.255.0");//设置IP起始为10.1.1.0,子网掩码255.255.255.0
Ipv4InterfaceContainer p2pInterfaces;//生成一个名叫p2pInterfaces的模组,用于存储有关于p2p节点们的IP地址的信息
//所有里面的IP都是起始为10.1.1.0,子网掩码255.255.255.0
p2pInterfaces = address.Assign (p2pDevices);//把p2pInterfaces给两个p2pDevices,也就是两个p2p device,IP分别为10.1.1.1和10.1.1.2
address.SetBase ("10.1.6.0", "255.255.255.0");//设置IP起始为10.1.2.0,子网掩码255.255.255.0
Ipv4InterfaceContainer csmaInterfaces;//生成一个名叫csmaInterfaces的模组,用于存储有关于csma节点们的IP地址的信息
//所有里面的IP都是起始为10.1.2.0,子网掩码255.255.255.0
csmaInterfaces = address.Assign (csmaDevices);//把csmaInterfaces给两个csmaDevices,也就是两个csma device,IP分别为10.1.2.1和10.1.2.2和10.1.2.3(默认3个csma)
address.SetBase ("10.1.3.0", "255.255.255.0");//设置IP起始为10.1.3.0,子网掩码255.255.255.0
address.Assign (staDevices);//staDevices自带interface,直接把10.1.3.1和10.1.3.2和10.1.3.3地址交给sta
address.Assign (apDevices);//apDevices自带interface,直接把10.1.3.4和10.1.2.4(AP同时也是第四个csma节点)地址交给ap
TCP/IP之上的就是应用层了,底层搭建完成后添加应用——UDP 回声 进去:
UdpEchoServerHelper echoServer (9);//创建一个udp 回声 服务器,也就是发送端(客户端)发过去一个UDP包,接收端(服务器)回一个UDP,类似于ping
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));//给csma所有的节点都安装UdpEchoServer
serverApps.Start (Seconds (1.0));//服务器1s启动
serverApps.Stop (Seconds (10.0));//服务器10s停止
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);//创建一个UDP 回声 客户端,客户端的地址基于测试吗地址,端口为9
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));//总共发送几个数据包,如果改为2,就发两次,每次一包,一包1024Bytes
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));//包与包之间的时间间隔
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));//一个包大小为1024Bytes
ApplicationContainer clientApps = echoClient.Install (wifiStaNodes.Get (nWifi - 1));//给sta也都装上UdpEchoClient
clientApps.Start (Seconds (2.0));//客户端2s启动
clientApps.Stop (Seconds (10.0));//客户端10s启动
最后配置路由表,打印抓包结果到文件,套路地启动和停止simulator:
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();//启用OSPF路由算法算出来全局最优路由表并且用这个表通信
Simulator::Stop (Seconds (10.0));//整个仿真程序10s停止
if (tracing)//如果打开--tracing=1,那么就保存抓包记录
{
phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);//设置抓包类型为80211射频
pointToPoint.EnablePcapAll ("third");//收集本脚本所有收发记录,名字前缀为 “third”
phy.EnablePcap ("third", apDevices.Get (0));//抓AP的无线包,含beacon
csma.EnablePcap ("third", csmaDevices.Get (0), true);//抓csma节点帧
}
Simulator::Run ();//启动模拟
Simulator::Destroy ();//终止模拟
return 0;//返回运行正常