在tutorial的这一章中,一共介绍了3种拓扑,分别使用first.cc、second.cc、third.cc三个程序。并且拓扑的形式是递增式的。
第一个拓扑是点对点链路(两个节点),第二个拓扑在点对点链路的基础上增加了一个4节点csma网络,第三个拓扑则是在前两个的基础上增加了wifi网络。
下面是我大概翻译的这一章节内容
拓扑搭建
根据tutorial中的内容,这章主要包括三部分:搭建总线拓扑、模型-属性-实现、搭建无线拓扑。下面分别介绍不同部分。
搭建总线拓扑
本章将前面介绍过的节点、链路、信道,等等结合起来,搭建一条总线型拓扑。链路上采用载波侦听多路访问协议(Carrier Sense Multiple Access, CSMA)。用于模拟一个简单的以太网络。真实以太网采用的是CSMA/CD协议,多了冲突检测部分。
在前面first.cc中我们使用了helper对象构造点对点链路,同样构造csma链路的时候我们也可以使用对应的helper对象。基本上,整个过程和构造点对点链路是一样的,除了安装channel协议的时候使用csma对应的类。
这部分对应的代码在second.cc中,同样可以在tutorial中找到。打开之后你会发现,基本上和first.cc差不多,这说明构造过程基本是一致的。那么本文也就不需要再细致讲解已经重复过的内容了。我会从中挑出前面没有介绍过的进行说明。
学过c语言的相信对变量的定义并不陌生。开始定义了两个变量,暂且不必管他们是干嘛的。看下面语句:
CommandLine cmd;
cmd.AddValue(“nCsma”,”Number of …”,nCsma);
cmd.Parse(argc,argv);
第一句定义命令行变量,最后一句说明开始对参数进行解析。主要介绍中间那句。指添加一个可以通过命令行修改的参数。AddValue函数具有有三个参数,1对应的参数名字,2是说明和帮助,3对应程序中的变量。在命令行的使用方式是(100是例子) :--nCsma=100。运行时可以如此:./waf --run “PROGRAM --nCsma=100”。
程序中使用csma的地方主要在helper处,如下:
CsmaHelper csma;
csma.SetChannelAttribute(“DataRate”,StringValue(“100Mbps”));
除了变量的定义使用CsmaHelper之外,可以看出其他地方没变化。因为csma和point-to-point一样,都是链路上的协议,并没有实体存在。在整个仿真环境中,它们必须依附其他的实例对象存在。唯一的体现个人感觉就是定义的名字。
在链路协议安装完成后,剩下的工作:安装协议栈,分配IP地址等等工作就和first.cc中一样了。由于拓扑较最开始的点对点,稍微复杂了一点点,程序中采用了路由机制:
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
直接调用ns3提供的某一路由算法,参阅nsnam的document,该函数的功能为:建立一个路由数据库,初始化仿真中的节点路由表。Make所有的节点成为路由器(也就是具有路由器的功能)。
在最后,程序添加了产生Pcap文件部分,前面说过,Pcap文件可以使用wireshark(有界面,使用方便,推荐)读取,其中记录着所有的信息,可以看到网络运行的状态(包、统计信息,等)。
PointToPoint.EnablePcapAll(“second”);
csma.EnablePcap(“second”, csmaDevice.get(1), true);
上面代码是什么意思呢?第一句指点对点网络中的所有网卡产生Pcap文件,而csma中则只选择了一个节点产生Pcap信息。
但是linux也自带工具识别pcap文件,即tcpdump命令。Tcpdump的使用可参考linux下的--help。具体读出来的信息格式需自行分析。
另外需要注意的是,second.cc中定义的拓扑是点对点网络和总线网络的结合,因此在分配ip地址的时候需要划分网段。
Models、Attribute、Reality
模型是现实的抽象,通过模型能够了解到部分外部世界。因此必须清楚模型所模拟的部分。例如:csma,通过阅读csma.h会发现这部分其实并没有对冲突检测进行建模。这就是与现实世界的差别。因此多花点时间了解现实的东西是个什么样子的,对于实际仿真的时候是非常有帮助的。
Ns3为每个模型提供了Attribute属性,用户可以通过修改Attribute来改变模型的行为。在csma中,考虑CsmaNetDevice两个属性:MTU和EncapsulationMode。首先MTU表示设备的最大传输单元。这是设备在单位时间内所能传输的最大数据单元。CsmaNetDevice中默认的MTU为1500字节(来自RFC894)。这个数值是从10Base-5(粗同轴电缆、基带传输方式、最大网段长度为500m)以太网中的最大数据包size—1518bytes。除去封装使用的18byte,剩下的刚好是1500字节。IEEE802.3网络规定的MTU为1492bytes,加上封装使用的8bytes,也刚好是1500字节。两种情况下,底层设备都只能发送1518字节,其中数据部分的size是不一样的。
在设置封装模式的时候,CsmaNetDevice提供的EncapsulationMode分别有Dix和Llc,这两种模型分别对应的是以太网(Ethernet)和LLC/SNAP框架。假设包大小为1500字节,但是使用LLC/SNAP框架封装,那么得到的整体大小为1526字节,而这个值在很多网络中是不允许的,因为规定的最大MTU为1518。这样的设置导致的结果就是仿真的结果可能距离实际情况差别比较大。
在second.cc这个例子中,通过命令行,可以很容易的建立100个csma节点(同样也可以建立500、600等)。但是实际网络中,最大的长度没有超过500米。基本上每隔2.5米就会有一个接头。像这些细节是在网络仿真中要注意的地方。
Ns3提供了较大的灵活性,大部分模型都支持自设置相关的Attribute。
……
个人感觉这一节更像是对使用NS3仿真的一些细节与建议,用户可选择性跳过。
搭建无线网络拓扑
同样,无线网络拓扑的搭建也是使用helper。前面提到PointToPoint和Csma网络的搭建过程几乎一致是因为它们只是协议上的差别。而无线网络则不同,除了协议上的差别,还涉及到移动设备的移动特性的刻画,每个接入的移动设备的表述(MAC、IP),wifi的无线信道刻画(与有线信道相区别),ssid,等等。因此和点对点网络、csma网络还是有较大区别的。
同样,ns3也给出相应的程序代码,即third.cc。这个程序中是在second.cc的基础上进行扩展的。即原有的“点对点链路+csma总线”,再加上wifi网络。将wifi网络与有线网络联系起来就需要有一个接入点(Access Point, AP),程序使用点对点链路中的一个节点作为AP。另外还定义了3个移动节点,连接到该AP上。
程序最开始定义了wifi节点数变量,以及对命令行参数的设置解析等过程。这个过程和csma的搭建一致。下面介绍与second.cc不同的代码的功能,首先:
NodeContainer wifiStaNodes;
wifiStaNodes.Create(nWifi);
NodeContainer wifiApNode = p2pNodes.Get(0);
节点容器相信并不陌生,第二行创建了几个wifi节点。最后一行将p2p链路中的节点0设置为wifi网络的AP。然后开始构造wifi设备和wifi节点之间的互连信道,那么首先就需要配置PHY以及信道helper。
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
YansWifiPhyHelper phy = YansWifiChannelHelper::Default();
程序为了简单,直接创建默认的Channel和PHY。然后再将所有的PHY与Channel联系起来,保证其共享同样的无线媒介。
phy.SetChannel(channel.Create());
PHY层配置好之后,开始配置MAC层(程序使用的是Non-Qos MAC)。
WifiHelper wifi = WifiHelper::Default();
wifi.SetRemoteStationManager(“ns3::AsrfWifiManager”);
NqosWifiMacHelper mac = NqosWifiMacHelper::Default();
SetRemoteStationManager其实是设置了速率控制算法。这里的速率在tutorial中也没有说清楚,我觉得应该是wifi信道的数据传播速率。下面设置基础网络的SSID(相信大家对这个并不陌生,全称是service set identifier)以及MAC。
Ssid ssid = Ssid (“ns3-ssid”);
mac.SetType(“ns3-StaWifiMac”, “Ssid”, SsidValue(ssid), “ActiveProbing”, False);
第一个参数是wifimac的type。紧接着依次为参数1的名字、value,参数2的名字,value…….。其中probing=false,说明该mac不会发送probe(查询)请求。至此,构建wifi网络需要的PHY,MAC和NODE都已经具备了,直接使用INSTALL安装即可。
NetDeviceContainer ndc = wifi.Install(phy, mac, wifiStaNodes);
注意,以上是StaNodes,指移动的设备节点,并不包括AP。AP的设置稍微有点不同(在于mac的type),具体如下:
mac.SetType(“ns3-ApWifiMac”, “Ssid”, SsidValue(ssid), “ActiveProbing”, False);
NetDeviceContainer ndc = wifi.Install(phy, mac, wifiApNodes);
接下来,除了AP节点固定之外,其他wifi节点都应该是移动的、随机的位置。同样这部分也使用Helper来帮助我们,叫做MobilityHelper。
MobilityHelper mobility;
Mobility.SetAllocation(“ns3::GridPositionAllocator”, “MinX”, VALUE1, “MinY”, VALUE2, “DeltaX”, VALUE3, “DeltaY”, VALUE4, “GridWidth”, VALUE5, “LayoutType”, VALUE6).
显然可以看出上面的语句定义了一个移动模型,设定的是二维的网格空间。初始化了节点的移动空间。其中,参数1为移动模型的类型,剩下的属性参数俩俩分别为“名字+VALUE”。很显然,MinX,MinY,DeltaX,DeltaY,GridWidth,LayoutType分别为最小坐标(X,Y)、坐标增量Delta、网格宽度、布局类型。
规定好了活动范围之后,剩下的事就该规定wifi节点如何运动了。
mobility.SetMobilityModel(“ns3::RandomWalk2dMobilityModel”, “Bounds”, RectangleValue());
第一个参数是指节点移动的方式,其次是移动的矩阵。将移动模型安装到StaNodes中。
Mobility.Install(wifiStaNodes);
移动节点的mobility和AP的mobility不同,所以也需要重新设计AP的部分。
mobility.SetMobilityMode(“ns3::ConstantPositionMobilityModel”);
mobility.Install(wifiApNode);
到这一步,无线网络已经配置完毕。剩下的过程和first.cc、second.cc没什么区别,也就不在做介绍了。
可能在运行之后,只能看到数字的变化。如果想要看到图像效果,那么推荐使用插件NetAnim和PyViz,这是ns3支持的两种图形化界面。