基于AODV路由协议的网络通信程序(代码实现)

头文件

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/aodv-helper.h"
#include "ns3/udp-echo-helper.h"
#include "ns3/netanim-module.h"

"ns3/core-module.h":引入NS3的核心模块,包括NS3的基本功能和常用类;
"ns3/network-module.h":引入NS3的网络模块,包括网络设备、协议栈和网络拓扑等;
"ns3/mobility-module.h":引入NS3的移动性模块,用于模拟节点的移动性和位置;
"ns3/wifi-module.h":引入NS3的WiFi模块,用于模拟WiFi网络和设备;
"ns3/internet-module.h":引入NS3的Internet模块,包括IPv4、TCP、UDP等协议的实现;
"ns3/aodv-helper.h":引入NS3的AODV助手,用于配置和管理AODV路由协议;
"ns3/udp-echo-helper.h":引入NS3的UDP回显助手,用于配置和管理UDP回显应用;
"ns3/netanim-module.h":引入NS3的NetAnim模块,用于创建和可视化网络拓扑。

命名空间

using namespace ns3;

将命名空间"ns3"引入当前代码文件的作用域中,以便可以直接使用该命名空间下的类、函数和变量,而无需显式地指定命名空间。

主函数

uint32_t numNodes = 5;
double totalTime = 30.0;

首先定义了模拟网络中的节点个数以及模拟持续时间。

CommandLine cmd;
cmd.Parse(argc, argv);

该语句使用户能够通过命令行传递参数来改变脚本中的变量。

NodeContainer nodes;
nodes.Create(numNodes);

该段代码用于创建和管理节点:此处使用 NodeContainer 类中的成员函数 Create() 生成 个节点,并将这些节点添加到 NodeContainer 中,随后返回包含了创建的节点集合的 NodeContainer 对象,此时节点什么都没有做。

WifiHelper wifi;
wifi.SetStandard(WIFI_STANDARD_80211b);
wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
                             "DataMode", StringValue("DsssRate11Mbps"),
                             "ControlMode", StringValue("DsssRate1Mbps"));

该段语句用于配置无线网络中的一些基本参数和属性,以实现对无线网络的模拟和仿真:
① 首先使用 WifiHelper 类创建一个无线网络;
② 随后使用成员函数 SetStandard() 设置无线网络的标准并自动配置相关参数,从而实现对 WiFi 网络的定制和模拟,此处使用的标准为 802.11b;
⑤ 最后使用成员函数 SetRemoteStationManager() 设置无线网络的远程站点管理器类型及其属性值,其中参数一指定了远程站点管理器类型,参数二声明了第一个属性名称为 DataMode ,参数三设置了 DaraMode 属性的值,参数四声明了第二个属性名称为 ControlMode ,参数五设置了 ControlMode 属性的值。

WifiMacHelper wifiMac;
wifiMac.SetType("ns3::AdhocWifiMac");

该段语句用于配置无线网络的 MAC 层,负责管理数据传输:
① 首先创建了一个名为 wifiMac 的 WifiMacHelper 对象,用于配置无线网络的 MAC 层;
② 随后使用成员函数 SetType() 设置 MAC 层的类型为"ns3::AdhocWifiMac";此处 SetType 函数仅设置了 MAC 层的类型,并未设置 MAC 层的属性。该代语句只实现了 MAC 层的配置,并未将 MAC 层与其他组件进行结合。

YansWifiPhyHelper wifiPhy;
wifiPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
YansWifiChannelHelper wifiChannel;
wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel");
wifiPhy.SetChannel(wifiChannel.Create());

该段语句用于配置无线网络的物理层和信道模型,以实现对无线信号的传输和传播进行模拟和仿真:
① 该段语句前两行首先创建一个 YansWifiPhyHelper 对象,用于配置网络的物理层,之后使用 YansWifiPhyHelper 类的成员函数 SetErrorRateModel() 将误码率模型设置为"NistErrorRateModel" (需要注意的是 YansWifiPhyHelper 类继承自 WifiPhyHelper 类,因此,YansWifiPhyHelper 类具有 WifiPhyHelper 类的所有功能和方法,它可以看作是在 WifiPhyHelper 类的基础上进行了扩展,增加了一些 YANS 模型特定的配置选项);
② 第三至五行首先创建一个 YansWifiChannelHelper 对象,用于配置网络的信道,随后使用成员函数 SetPropagationDelay() 设置信道的传播延迟模型为 ConstantSpeedPropagationDelayModel ,该模型假设信号传播的速度是恒定的,然后通过 AddPropagationLoss() 添加传播损耗模型为 FriisPropagationLossModel ,该模型基于Friis公式计算信号在自由空间中的衰减和传播损耗;
③ 无线网络的物理层和信道配置完成后,第六行语句先通过 YansWifiChannelHelper 类中的成员函数 Create() 创建一个实际的信道模型对象,之后将信道模型对象分配给 wifiPhy 的信道属性,从而将信道模型应用于物理层,建立了物理层和信道之间的关联。

NetDeviceContainer devices;
devices = wifi.Install(wifiPhy, wifiMac, nodes);

该段语句用于将配置好的 WiFi 设备安装到指定的节点上,以建立节点和 WiFi 设备之间的连接:
① 第一行语句创建了 NetDeviceContainer 对象 devices ,用于存储安装的 WiFi 设备;
② 第二行语句通过 WiFiHelper 类的 Install() 方法,将 WiFi 设备安装到指定的节点上,具体来说,将 WiFi 设备安装在给定的物理层对象 wifiPhy 和 MAC 层对象 wifiMac 上,并将其连接到给定的节点集 nodes 上,随后返回为 devices 设备容器。

AodvHelper aodv;
InternetStackHelper internet;
internet.SetRoutingHelper(aodv);
internet.Install(nodes);

该段代码用于配置AODV路由协议,并将其安装在指定节点上:
① 第一行语句创建了一个 AodvHelper 对象,用于用于配置AODV路由协议;
② 第二行语句创建了一个 InternetStackHelper 对象,用于用于配置网络协议栈;
③ 第三行语句使用 InternetStackHelper 类中的 SetRoutingHelper() 方法,将 ① 创建的 "aodv" 设置为 "internet" 的路由协议 (此处 SetRoutingHelper() 方法的参数为 Ipv4RoutingHelper 类的对象,NS3 提供了多个实现了 Ipv4RoutingHelper 接口的路由协议助手类,AodvHelper 便在其中);
④ 第四行语句使用 InternetStackHelper 类中的 Install() 方法,将配置好的网络协议栈安装在指定的节点上。

Ipv4AddressHelper ipv4;
ipv4.SetBase("10.0.0.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = ipv4.Assign(devices);

该段代码用于为 WiFi 设备配置 IPv4 地址:
① 第一行语句创建了 Ipv4AddressHelper 对象,用于配置 IPv4 地址;
② 第二行语句使用 Ipv4AddressHelper 类中的 SetBase() 方法设置基准和网络掩码:参数一是网络地址,表示将分配给 WiFi 设备的 IPv4 地址的起始地址,参数二是子网掩码,用于指定IPv4地址的网络前缀;
③ 第三行语句首先使用 Ipv4AddressHelper 类中的 Assign() 方法为 devices 分配 IPv4 地址(分配的地址是根据之前通过 SetBase() 方法设置的地址基准和子网掩码进行计算的),随后将分配的 IPv4 地址和接口信息存储在 Ipv4InterfaceContainer 类的对象 interfaces 中(充当接口容器)。

MobilityHelper mobility;
mobility.SetPositionAllocator("ns3::GridPositionAllocator",
                              "MinX", DoubleValue(0.0),
                              "MinY", DoubleValue(0.0),
                              "DeltaX", DoubleValue(5.0),
                              "DeltaY", DoubleValue(5.0),
                              "GridWidth", UintegerValue(2),
                              "LayoutType", StringValue("RowFirst"));
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(nodes);

该段语句用于在 NS3 中配置移动模型,并将其安装在指定的节点上,以模拟节点的移动行为:
① 第一个语句创建了 MobilityHelper 对象 mobility,用于配置节点的移动模型;
② 第二个语句使用 SetPositionAllocator() 方法设置位置分配器,从而决定节点在仿真中的初始位置,其中第一个参数是位置分配器的类型,此处使用网格分布,用于将节点在二维网格上均匀分布,后续参数设置了移动模型中的参数,第二、三个参数设置了 X 轴最小位置为 (0.0),第四、五个参数设置 Y 轴最小位置为 (0.0),第五、六个参数设置节点在 X 轴上的间距为 5.0,第六、七个参数设置节点在 Y 轴上的间距为 5.0,第八、九个参数设置网格的宽度为 2,即每行最多有 2 个节点,第十、十一个参数设置节点的布局方式为 "RowFirst" ,即首先填充每一行的节点,然后再进行下一行的节点填充;
③ 第三个语句使用 SetMobilityModel() 方法设置节点的移动模型为 "ns3::ConstantPositionMobilityModel" ,表示节点的位置是恒定不变的,即节点不进行实际的移动;
④ 第四个语句使用 MobilityHelper 类的 Install() 方法将配置好的移动模型安装在指定的节点上。

UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(nodes.Get(numNodes - 1));
serverApps.Start(Seconds(1.0));
serverApps.Stop(Seconds(totalTime));

该段语句用于配置和创建一个UDP回显服务器,并将该服务器端的应用程序安装在指定的节点上:
① 第一行语句声明了一个 UdpEchoSeverHelper 对象 echoSever ,并设置服务器监听的端口号为9;
② 第二行语句首先通过 NodeContainer 类的成员函数 Get() 获取  nodes 中的第 numNodes-1 个节点,即获取最后一个节点,随后使用 UdpEchoSeverHelper 类中的 Install() 方法将 UDP 回显服务器应用程序安装在最后一个节点上,此时回显服务器的应用完成初始化;
③ 第三、四行语句使 udp 回显服务器端应用程序在 1s 时开启并在 totalTime 时停止。

UdpEchoClientHelper echoClient(interfaces.GetAddress(numNodes - 1), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue(1));
echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));

该段语句用于配置和创建一个UDP回显客户端,并设置客户端的属性,与服务器端的设置类似,然而客户端需要设置五个属性,前两个属性是在 UdpEchoClientHelper 的构建过程中被设置的:
① 第一行语句创建了一个 UdpEchoClientHelper 对象 echoClient,同时获取 interfaces 中的最后一个地址,即之前为设备分配的 IPv4 地址信息中的最后一个地址,作为 UDPEcho 客户端的目标地址,同时设置客户端向目标地址的 9 号端口发送 UDP 数据包;
② 第二至四行语句分别设置了客户端的属性:第二行设置客户端发送的最大数据包数为 1,即客户端只发送一个 UDP 数据包,第三行设置数据包之间的发送间隔为 1 秒,即每秒发送一个 UDP 数据包,第三行设置每个 UDP 数据包的大小为 1024 字节,即每个数据包发送 1024 字节的数据。

ApplicationContainer clientApps = echoClient.Install(nodes.Get(0));
clientApps.Start(Seconds(2.0));
clientApps.Stop(Seconds(totalTime));

该段语句用于将该客户端应用程序安装在网络中的指定节点上,并设置客户端的启动和停止时间:
① 第一行语句使用 NodeContainer 类中的 Get() 方法获取到第一个节点的指针,随后使用 UdpEchoClientHelper 类中的 Install() 方法在第一个节点上创建 udp 回显客户端应用程序,并存储在一个 ApplicationContainer 对象中;
② 第二、三行语句使 udp 回显客户端应用程序在仿真开始后的 2 秒钟启动,并在仿真运行的 totalTime 秒后停止。

完整代码

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/aodv-helper.h"
#include "ns3/udp-echo-helper.h"
#include "ns3/netanim-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("AODVExample");

int main(int argc, char *argv[])
{
  uint32_t numNodes = 5;    //定义节点数量和模拟时间
  double totalTime = 30.0;

  CommandLine cmd;    //使用户能用命令行访问代码中的全局变量和NS3中的属性系统
  cmd.Parse(argc, argv);

  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
  
  NodeContainer nodes;    //创建节点
  nodes.Create(numNodes);

  //使用WifiHelper类创建一个无线网络
  WifiHelper wifi;
  //使用成员函数SetStandard()设置无线网络的标准为 802.11b
  wifi.SetStandard(WIFI_STANDARD_80211b);
  //SetRemoteStationManager()设置数据传输模式和控制模式,以控制数据和空指帧的传输速率
  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
                               "DataMode", StringValue("DsssRate11Mbps"),
                               "ControlMode", StringValue("DsssRate1Mbps"));

  WifiMacHelper wifiMac;
  wifiMac.SetType("ns3::AdhocWifiMac");

  YansWifiPhyHelper wifiPhy;
  wifiPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
  YansWifiChannelHelper wifiChannel;
  wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
  wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel");
  wifiPhy.SetChannel(wifiChannel.Create());

  NetDeviceContainer devices;
  devices = wifi.Install(wifiPhy, wifiMac, nodes);

  AodvHelper aodv;
  InternetStackHelper internet;
  internet.SetRoutingHelper(aodv);
  internet.Install(nodes);

  Ipv4AddressHelper ipv4;
  ipv4.SetBase("10.0.0.0", "255.255.255.0");
  Ipv4InterfaceContainer interfaces = ipv4.Assign(devices);

  MobilityHelper mobility;
  mobility.SetPositionAllocator("ns3::GridPositionAllocator",
                                "MinX", DoubleValue(0.0),
                                "MinY", DoubleValue(0.0),
                                "DeltaX", DoubleValue(5.0),
                                "DeltaY", DoubleValue(5.0),
                                "GridWidth", UintegerValue(2),
                                "LayoutType", StringValue("RowFirst"));
  mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
  mobility.Install(nodes);

  UdpEchoServerHelper echoServer(9);
  ApplicationContainer serverApps = echoServer.Install(nodes.Get(numNodes - 1));
  serverApps.Start(Seconds(1.0));
  serverApps.Stop(Seconds(totalTime));

  UdpEchoClientHelper echoClient(interfaces.GetAddress(numNodes - 1), 9);
  echoClient.SetAttribute("MaxPackets", UintegerValue(1));
  echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0)));
  echoClient.SetAttribute("PacketSize", UintegerValue(1024));

  ApplicationContainer clientApps = echoClient.Install(nodes.Get(0));
  clientApps.Start(Seconds(2.0));
  clientApps.Stop(Seconds(totalTime));

  Simulator::Stop(Seconds(totalTime));
  AnimationInterface anim("adhoc.xml"); 
  Simulator::Run();
  Simulator::Destroy();

  return 0;
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值