ns-3脚本初识——CSMA有线网络:second脚本

ns-3脚本初识——CSMA有线网络:second脚本

ps:本文所有文件和目录的默认根目录均为ns-3.29/。

该脚本默认拓扑结构如下:

       10.1.1.0
  n0 -------------- n1   n2   n3   n4
    point-to-point   |    |    |    |
                   ===================
                       LAN 10.1.2.0

n0和n1实现点到点通信(与first.cc中相似),n1~n4是个CSMA有线局域网。网络可以实现n0经由n1,和n4进行通信。

1.代码规范

 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

2.头文件

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"

3.命名空间

using namespace ns3;

4.日志

NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");

5.主函数声明

int 
main (int argc, char *argv[])
{
…
}

6.主函数准备工作

  //定义bool变量,用于决定是否开启2个UdpApplication的Logging日志组件,默认true开启
  bool verbose = true;
  uint32_t nCsma = 3;//变量,用于定义csma网络中额外有多少个node,此处为3

  CommandLine cmd; //命令行
  cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
  //“nCsma”参数控制着脚本中CSMA网络中额外节点的数量,其对应的C++同名变量是非整型数nCsma
  cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
  //“verbose”参数设置是否开启logging
  cmd.Parse (argc,argv);

  if (verbose)
    {
      LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
      LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
    }

  nCsma = nCsma == 0 ? 1 : nCsma;

7.创建网络拓扑

  //创建使用P2P链路的两个节点
  NodeContainer p2pNodes;
  p2pNodes.Create (2);

  //创建csma网络节点
  NodeContainer csmaNodes;
  csmaNodes.Add (p2pNodes.Get (1));//将P2P的节点1加到CSMA网络中
  csmaNodes.Create (nCsma);//再创建额外的3个节点

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

  //安装P2P网卡到P2P网络节点
  NetDeviceContainer p2pDevices;//创建网络设备
  p2pDevices = pointToPoint.Install (p2pNodes);//连接节点与信道

  CsmaHelper csma;//CSMA信道助手类
  //设置CSMA传输速率和传播延迟,注意传输速率有channel指定,而非device属性。(CSMA不允许同一信道上有多个不同数据率的设备)
  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

  //安装CSMA网卡到CSMA网络节点
  NetDeviceContainer csmaDevices;
  csmaDevices = csma.Install (csmaNodes);

8.安装TCP/IP协议族

  //安装TCP/IP协议栈
  InternetStackHelper stack;
  stack.Install (p2pNodes.Get (0));
  stack.Install (csmaNodes);

  Ipv4AddressHelper address;//为网络设备分配IP地址
  address.SetBase ("10.1.1.0", "255.255.255.0");//安排P2P网段的地址
  Ipv4InterfaceContainer p2pInterfaces;
  p2pInterfaces = address.Assign (p2pDevices);

  address.SetBase ("10.1.2.0", "255.255.255.0");//安排CSMA网段的地址
  Ipv4InterfaceContainer csmaInterfaces;
  csmaInterfaces = address.Assign (csmaDevices);

9.安装应用层

  UdpEchoServerHelper echoServer (9);//服务端设置端口号

  //在节点4中安装服务端程序
  ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
  serverApps.Start (Seconds (1.0));
  serverApps.Stop (Seconds (10.0));

  //配置客户端程序属性
  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

  //在节点0中安装客户端程序
  ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
  clientApps.Start (Seconds (2.0));
  clientApps.Stop (Seconds (10.0));

10.设置路由

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

在创建CSMA网络时曾提到一个p2pNodes.Get(1)节点,这个节点有PointToPointNetDevice和CsmaNetDevice两个网络设备,分别连接PPP网络和CSMA网络,在second脚本的地址分配中,这两个网络属于不同的子网,这就需要连接两个子网的p2pNodes.Get(1)节点具有路由功能,这样才能正确转发从PPP子网发往CSMA子网的分组。反之亦然。

ns-3有线网络最常用的路由协议之一是全局路由。全局路由通过开放式最短路径优先(OSPF)路由算法计算有线网络拓扑中每两个节点的最短路径,并为每个节点生成路由表。

对于IPv4协议,全局路由设置一般是通过在脚本中调用助手类Ipv4GlobalRoutingHelper的PopulateRoutingTables()函数完成的。

11.数据追踪

  pointToPoint.EnablePcapAll ("second");  //开启P2PHelper类对象的pcap,second为保存文件的前缀名
  csma.EnablePcap ("second", csmaDevices.Get (1), true);//开启CSMA类对象的pcap

使用CSMA网段索引为1的设备(第二个)进行sniff 嗅探,True开启promiscuous mode 混杂模式。

12.启动与结束

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

13.上机实践

在ns-3.29(或其他的版本)目录下运行second模拟脚本(需要在编译时启动enable-examples选项,不然就将脚本放到scratch目录下)。

./waf --run second

运行结果如下:

At time 2s client sent 1024 bytes to 10.1.2.4 port 9
At time 2.0078s server received 1024 bytes from 10.1.1.1 port 49153
At time 2.0078s server sent 1024 bytes to 10.1.1.1 port 49153
At time 2.01761s client received 1024 bytes from 10.1.2.4 port 9

输出信息显示了UdpEcho应用的行为:2s时,节点4(10.1.2.4)发送了一个大小为1024B的数据包给节点0(10.1.1.1)。经过0.0078s,节点0成功接收到数据包后返回一个同样大小的数据包。再经过相同的时间,节点4接收到该返回数据包。

如果回到根目录ns-3.29/,将会发现3个跟踪文件,如下图所示:
ns-3脚本初识——CSMA有线网络:second脚本_第1张图片

可以看出,这3个文件的命名具有相同的形式:< name >-< node >-< device >.pcap。例如,第一个文件second-0-0.pcap意味着是来自点对点网络设备上节点0、设备0的pcap跟踪文件。在文章开头的拓扑说明中可以看到,节点0是点到点链路最左端的节点,节点1既有点到点设备又有CSMA设备。节点2是CSMA网络上的第一个”额外“节点,其设设备被选为捕捉混杂模式跟踪的设备。

首先查看最左端点到点节点(节点0),输入如下:

tcpdump -nn -tt -r second-0-0.pcap

可以看到显示的pcap文件的内容:

reading from file second-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024

第一行表示链接类型是PPP(点到点)。第二行中,回显数据分组离开节点0,途经IP地址为10.1.1.1的关联设备,奔向IP地址为战.1.2.4的最右边的CSMA节点。这个数据分组移动到点到点链路,被节点1上的点到点的网络设备接收。
接下来查看右端点到点节点(节点1),输入如下:

tcpdump -nn -tt -r second-1-0.pcap

可以看到显示的pcap文件的内容:

reading from file second-1-0.pcap, link-type PPP (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024

这里的链路类型也是PPP。来自IP地址10.1.1.1的数据分组(在2.000000s被发送到IP地址中0.1.2.4)出现在该接口上,在这个节点上,数据分组会被转发到CSMA接口,然后去往最终的目的地。
再看看节点2的跟踪文件,输入如下:

tcpdump -nn -tt -r second-2-0.pcap

节点2作为CSMA网络混杂嗅探节点的情况如下:

reading from file second-2-0.pcap, link-type EN10MB (Ethernet)
2.007698 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, length 50
2.007710 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
2.013815 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, length 50
2.013828 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024

链路类型为”以太网“,总线网络需要ARP地址解析协议。节点1知道它需要发送数据分组到IP地址10.1.2.4,但它不知道相应节点的MAC地址,于是在CSMA网络(ff:ff:ff:ff:ff:ff)上广播寻找IP地址为10.1.2.4的设备。在这种情况下,最右边节点回答其MAC地址为00:00:00:00:00:06。注意,节点2不直接参与到这个交换中,而是嗅探网络并报告它所看到的所有流量。

节点1设备1发送回显数据分组给IP地址为战.1.2.4的UDP回显服务器,服务器接收到回显请求后试图将数据分组发回给源头,服务器知道其地址在另一个网络(IP地址为10.1.2.1)上,但回显服务器的及诶点不知道第一个CSMA节点的MAC地址,所有如同第一个CSMA节点所做的,它发送了ARP。

输出可视化界面的代码如下:

w@wangl:~/tarballs/ns-allinone-3.29/ns-3.29$ ./waf --run second --vis

可视化界面如下:
ns-3脚本初识——CSMA有线网络:second脚本_第2张图片鼠标指向图中节点,会得到该节点相关信息:
ns-3脚本初识——CSMA有线网络:second脚本_第3张图片ns-3脚本初识——CSMA有线网络:second脚本_第4张图片ns-3脚本初识——CSMA有线网络:second脚本_第5张图片

你可能感兴趣的:(ns-3示例脚本)