ns3

ns3第三个例子构建无线网络拓扑

ns3例子

Posted by MZ on September 24, 2022

一、代码解读

#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
//
//   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

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");

bool verbose = true;
uint32_t nCsma = 3;
uint32_t nWifi = 3;

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.Parse (argc,argv);

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

前面部分的代码基本变化不大,主要是网络拓扑图放这里看一下。

后面开始定义各个节点,通道和网络设备

//点对点
NodeContainer p2pNodes;
p2pNodes.Create (2);

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

NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
//csma
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);

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

NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
//wifi
NodeContainer wifiStaNodes;
wifiStaNodes.Create (nWifi);
NodeContainer wifiApNode = p2pNodes.Get (0);

wifi的通道与网络设备与之前的点对点和以太网不一样,这里重点说明一下。

下一段代码构造 wifi 设备和这些 wifi 节点之间的互连通道。首先,我们配置 PHY 和通道帮助程序

//都是默认值
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();

phy.SetChannel (channel.Create ());

设置 MAC 参数与Ssid值,第二个语句创建一个 802.11 服务集标识符 (SSID) 对象,该对象将用于设置 MAC 层实现的“Ssid”的值。

WifiMacHelper mac;
Ssid ssid = Ssid ("ns-3-ssid");

最后是wifi助手

WifiHelper wifi;
NetDeviceContainer staDevices
mac.SetType ("ns3::StaWifiMac",
  "Ssid", SsidValue (ssid),
  "ActiveProbing", BooleanValue (false));

设置类型为标准wifiMac类型,ssid的值传入进去,还要最后一个参数活动探测设为false,这意味着探测请求不会由此帮助程序创建的 MAC 发送,并且工作站将侦听 AP 信标。

NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);

综上所述,构建Wifi的网络设备与通道一共需要四个帮助对象:

  1. PHY——YansWifiPhyHelper
  2. 信道——YansWifiChannelHelper
  3. Mac——WifiMacHelper
  4. wifi——WifiHelper

我们已经为所有 STA 节点配置了 Wi-Fi,现在我们需要配置 AP(接入点)节点。

mac.SetType ("ns3::ApWifiMac",
             "Ssid", SsidValue (ssid));
             
NetDeviceContainer apDevices;
apDevices = wifi.Install (phy, mac, wifiApNode);

ap与工作站共享同一个PHY和信道。

最后,移动STD节点,保持AP静止。

MobilityHelper mobility;

mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
  "MinX", DoubleValue (0.0),
  "MinY", DoubleValue (0.0),
  "DeltaX", DoubleValue (5.0),
  "DeltaY", DoubleValue (10.0),
  "GridWidth", UintegerValue (3),
  "LayoutType", StringValue ("RowFirst"));
//std移动
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
  "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));

mobility.Install (wifiStaNodes);
//ap静止
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode);

安装协议栈,配置ip地址

InternetStackHelper stack;
stack.Install (csmaNodes);
stack.Install (wifiApNode);
stack.Install (wifiStaNodes);

Ipv4AddressHelper address;

address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);

address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);

address.SetBase ("10.1.3.0", "255.255.255.0");
address.Assign (staDevices);
address.Assign (apDevices);

应用程序设置部分略过

全局路由

Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

我们刚刚创建的模拟永远不会“自然”停止。这是因为我们要求无线接入点生成信标。它将永远生成信标,这将导致模拟器事件无限期地安排在未来,因此我们必须告诉模拟器停止,即使它可能安排了信标生成事件。以下代码行告诉模拟器停止,这样我们就不会永远模拟信标并进入本质上是一个无限循环。

Simulator::Stop (Seconds (10.0));

跟踪系统

pointToPoint.EnablePcapAll ("third");
phy.EnablePcap ("third", apDevices.Get (0));
csma.EnablePcap ("third", csmaDevices.Get (0), true);

最后运行。