NS3实例分析third.cc_Building a Wireless Network Topology

来源:互联网 发布:儿童学古诗软件 编辑:程序博客网 时间:2024/05/16 03:58

转自:http://blog.sina.com.cn/s/blog_7ec2ab360102wxh3.html


这节我们将利用一个无线网络来进一步扩展关于NS3网络设备和信道的知识。其中,我们将看到WifiHelper,其作用类似于PointToPointHelper和CsmaHelper。

在example/tutorial下的third.cc脚本是second.cc的升级版,我们在third.cc中添加了Wifi网络。

 

 

一.third.cc代码

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

// Default Network Topology
// 网络拓扑结构
// Number of wifi or csma nodes can be increased up to 250
//                                           |
//                              Rank 0  Rank 1
// ----------------------------|----------------------------
//   Wifi 10.1.3.0
//                       AP
//  *     *      *      *
//  |                      10.1.1.0
// n5   n6   n7   n0 ------------------n1   n2   n3   n4
//                              point-to-point        |      |       |
//                                                        ===========
//                                                            LAN 10.1.2.0

//在p2p网络左边,我们添加了10.1.3.0的WiFi网络。其中n0为AP节点,n5、6、7为STA节点。与nCsma相似,我们可以通过设置nWifi来控制在仿真中出现的STA节点数。在仿真中一定存在一个AP节点!

 

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");

int
main (int argc, char *argv[])
{
  bool verbose = true;
  uint32_t nCsma = 3;
  uint32_t nWifi = 3;            // 在WiFi网络中,除了一个AP节点以外的STA节点数
  bool tracing = false;         // 在trace时,是否启用promiscuous模式,初始化为不启用

  CommandLine cmd;         // 向命令行参数系统添加属性
  cmd.AddValue ("nCsma", "Number of "extra" CSMA nodes/devices", nCsma);
  cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
  cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
  cmd.AddValue ("tracing", "Enable pcap tracing", tracing);

  cmd.Parse (argc,argv);

  

  // 查看csma和wifi节点的是有效数量,各不能超过250

  // Check for valid number of csma or wifi nodes
  // 250 should be enough, otherwise IP addresses
  // soon become an issue
  if (nWifi > 250 || nCsma > 250)
    {
      std::cout << "Too many wifi or csma nodes, no more than 250 each." << std::endl;
      return 1;
    }

 

 

  if (verbose)                                 // UDP日志启用判断
    {
      LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
      LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
    }

 

 

  NodeContainer p2pNodes;                         // 创建p2p节点,并且对设备、信道进行设置安装
  p2pNodes.Create (2);

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

  NetDeviceContainer p2pDevices;
  p2pDevices = pointToPoint.Install (p2pNodes);              

 

 

  NodeContainer csmaNodes;                    // 创建csma节点对象
  csmaNodes.Add (p2pNodes.Get (1));       // p2p网络中,索引为1的节点将同时作为csma节点
  csmaNodes.Create (nCsma);

  CsmaHelper csma;
  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

  NetDeviceContainer csmaDevices;
  csmaDevices = csma.Install (csmaNodes);

 

 

 

  NodeContainer wifiStaNodes;                  // 创建STA节点对象
  wifiStaNodes.Create (nWifi);
  NodeContainer wifiApNode = p2pNodes.Get (0);           // 创建AP节点,让p2p网络中,索引为0的节点同时作为AP节点

  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();        // 配置信道对象为默认参数
  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();     // 配置物理层对象为默认参数
  phy.SetChannel (channel.Create ());     // 创建一个信道对象并与PHY对象相连,以确保所有由YansWifiPhyHelper创建的物理层对象共享相同的底层信道,即它们共享相同的无线媒介并可以相互交流干预。

 

 

 

  WifiHelper wifi;
  wifi.SetRemoteStationManager ("ns3::AarfWifiManager");     // SetRemoteStationManager()告诉helper用什么速率控制协议类型。这里是用AARF协议。

  WifiMacHelper mac;    // tutorial上是:NqosWifiMacHelper mac=NqosWifiMacHelper ::Default();
  Ssid ssid = Ssid ("ns-3-ssid");                 // 利用Ssid()方法,设置服务集标识
  mac.SetType ("ns3::StaWifiMac",           // 设置MAC类型为ns3::StaWifiMac
               "Ssid", SsidValue (ssid),
               "ActiveProbing", BooleanValue (false));           //探测请求不会发送给由这个helper创建出来的MAC层

  NetDeviceContainer staDevices;
  staDevices = wifi.Install (phy, mac, wifiStaNodes);     //安装STA节点的mac层和物理层。

 

 

 

  mac.SetType ("ns3::ApWifiMac",                                         //MAC层类型为ApWifiMac
               "Ssid", SsidValue (ssid));

  NetDeviceContainer apDevices;
  apDevices = wifi.Install (phy, mac, wifiApNode);               //安装AP节点的mac层和物理层。

 

 

 

  MobilityHelper mobility;

  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",     //位置分配器类型:网格位置分配器,分配每个节点的初始位置
                                 "MinX", DoubleValue (0.0),
                                 "MinY", DoubleValue (0.0),
                                 "DeltaX", DoubleValue (5.0),   //x轴的间隔
                                 "DeltaY", DoubleValue (10.0),
                                 "GridWidth", UintegerValue (3),    //网格宽度

                                 "LayoutType", StringValue ("RowFirst"));     //布局类型

  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",      //运动模型:在固定范围内节点以任意速度任意方向移动
                             "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));     //移动范围设置
  mobility.Install (wifiStaNodes);      //将移动模型安装在STA节点上

  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");   //设置AP节点的移动模型:固定
  mobility.Install (wifiApNode);    //在AP节点上安装移动模型

 

 

  InternetStackHelper stack;    //安装协议栈
  stack.Install (csmaNodes);
  stack.Install (wifiApNode);
  stack.Install (wifiStaNodes);

 

 

  Ipv4AddressHelper address;                                           //分配IP地址

  address.SetBase ("10.1.1.0", "255.255.255.0");               //p2p地址从:10.1.1.0开始
  Ipv4InterfaceContainer p2pInterfaces;
  p2pInterfaces = address.Assign (p2pDevices);

  address.SetBase ("10.1.2.0", "255.255.255.0");                 //csma地址从:10.1.2.0开始
  Ipv4InterfaceContainer csmaInterfaces;
  csmaInterfaces = address.Assign (csmaDevices);

  address.SetBase ("10.1.3.0", "255.255.255.0");                 //WiFi地址从:10.1.3.0开始
  address.Assign (staDevices);
  address.Assign (apDevices);

 

 

 

  UdpEchoServerHelper echoServer (9);        //csma网络中的最后一个节点作为服务器

  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));

  ApplicationContainer clientApps =
    echoClient.Install (wifiStaNodes.Get (nWifi - 1));    //将客户端安装在WiFi网络中的最后一个STA节点上    
  clientApps.Start (Seconds (2.0));
  clientApps.Stop (Seconds (10.0));

 

 

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

  Simulator::Stop (Seconds (10.0));       //仿真不会自动停止。因为AP会一直产生信标。所以,我们需要告诉仿真器暂停。

  if (tracing == true)
    {
      pointToPoint.EnablePcapAll ("third");
      phy.EnablePcap ("third", apDevices.Get (0));   //WifiHelper类中没有Enalepcap()成员函数。
      csma.EnablePcap ("third", csmaDevices.Get (0), true);
    }

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

 

 

编译运行:

NS3实例分析third.cc_Building <wbr>a <wbr>Wireless <wbr>Network <wbr>Topology

 

 

注意!脚本中,tracing初始化为false,所以需要用cmd命令,将其改成true,然后就会在ns-3.25目录下,生成4个.pcap文件:

NS3实例分析third.cc_Building <wbr>a <wbr>Wireless <wbr>Network <wbr>Topologythird-0-0.pcap:p2p中第一个节点,n0

third-0-1.pcap:wifi网络中的AP节点,n0

third-1-0.pcap:p2p中第二个节点,n1
third-1-1.pcap:csma中的第一个节点,n1
 

读取third-0-1.pcap文件:

NS3实例分析third.cc_Building <wbr>a <wbr>Wireless <wbr>Network <wbr>Topology

 

为了展现STA节点在仿真过程中确实是运动的,我们连接MobilityModel航线改变追踪源。

在NS3中,tracing系统分为trace发送端和trace接收端。我们将用移动模型预定的航线改变追踪源来产生追踪事件。我们需要写一个trace接收端来与发送端相连,这样我们将得到更多的信息。

代码添加如下:

在NS_LOG_COMPONENT_DEFINE后添加:

void
CourseChange (std::string context, Ptr model)
{
  Vector position = model->GetPosition();
  NS_LOG_UNCOND (context <<
    " x = " << position.x << ", y= " << position.y);
    
 //从运动模型中挑出位置信息,并且无条件地记录节点的x、y信息。

为了使客户端无线节点每次改变位置时就调用上述的函数。
在Simulator::Run前添加:

std::ostringstream oss;                     //输出我们想要连接的事件的追踪命名空间路径
oss <<
  "/NodeList/" << wifiStaNodes.Get (nWifi - 1)->GetId () <<
  "/$ns3::MobilityModel/CourseChange";

 Config::Connect (oss.str (), MakeCallback (&CourseChange));          //通过调用Config::Connect将节点7的追踪发送端和接收端相连,并且传递了命名空间路径

 

运行结果,显示了节点7的位置变化:



 

Yans-wifi-helper.h:

https://www.nsnam.org/docs/release/3.25/doxygen/yans-wifi-helper_8h_source.html

0 0