ns-3_ Day 0

版本 ns3.31
OS Ubuntu 18.04

ns-3是什么

是一个网络仿真工具,并不是ns-2的扩展而是一个全新的项目。
ns-3官方文档给出了详尽的下载、安装方案。完整的主目录如下:
image.png

  • waf是基于Python开发的编译工具,从ns3.36开始替换为cmake
  • scratch存放脚本文件(C++),也就是要运行的仿真过程。waf会自动到这里找脚本文件。
  • build是编译ns-3完成后得到的目录,包含用到的共享库和头文件。
  • src是模块源代码目录,每个模块占据一个目录,且都有如下结构:

image.png

  • binding是模块用于绑定Python语言的;
  • model是模块主代码;
  • wscript是waf编译该模块的根据。

ns-3默认带有下面的模块:
image.png

core ns-3的基本机制,所有的ns-3自带模块都依赖于此模块运行。
network 网络数据packet模块
Internet 实现网络协议族
application 几种常用的应用层协议
mobility 移动设备仿真模型
topology-read 读取制定轨迹文件数据,按照指定格式生成相应的网络拓扑
energy 模仿移动设备的能量管理
status 仿真数据收集、统计
tools 统计工具
visualizer 可视化界面工具PyViz
netanim 动画演示工具NetAnim
propagation 传播模型
flow-monitor 流量监控模块

除此之外,还有一些经典的网络模型:

point-to-point 点对点通信网络
csma IEEE 802.3以太网,包括MAC、物理层和媒体信道
mesh IEEE802.11s的无线mesh网络
WI-FI IEEE802.11a/b/g的无线网络,可以是由基础设施的也可以是ad hoc网络
wimax IEEE802.16的无线城域网络
LTE 3GPP主导的通用移动通信系统技术的长期演进
UAN 水声通信网络,方针水下网络场景,实现了信道、物理层和MAC

ns-3仿真脚本示例

通过下面这个示例,了解如何使用ns-3进行想要的仿真过程。

examples/tutorial/first.cc

//这些头文件就是引用 build/ns3/ 下的
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
// Default Network Topology
//
// 10.1.1.0
// n0 -------------- n1
// point-to-point
//
using namespace ns3;
// 用字符串定义日志组件(Component)
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
int
main (int argc, char *argv[])
{
CommandLine cmd (__FILE__);
cmd.Parse (argc, argv);
Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
NodeContainer nodes;
// 创建2个节点,可以视为2台“计算机”在网络中代表的点
nodes.Create (2);
// Helper类的作用是:把模块常见的工作抽象出来方便使用
PointToPointHelper pointToPoint;
// 一次P2P网络连接实际上就是“设备-信道-设备”的模型,如下设置:
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer devices;
// 按照上面的设置,配置设备和信道
devices = pointToPoint.Install (nodes);
// 主要配置的是IP层
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
// 把选好的ip地址分配到设备
Ipv4InterfaceContainer interfaces = address.Assign (devices);
// 安装应用程序并设置端口号
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
// 使echo服务在1s开始并在10s时结束
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
// MaxPacket属性告诉客户端所允许模拟器件发送的最大数据packet个数
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
// Interval属性告诉客户端在2个packet之间的时间
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
// PacketSize属性告诉客户端每个packet发送多少byte
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
// 实际上就是启动 serverApps和clientApps
Simulator::Run ();
Simulator::Destroy ();
return 0;
}

上面的示例代码可以分解为以下结构:

  1. 头文件、命名空间 允许在该脚本中使用LOG系统中的宏定义
  2. NS_LOG_COMPONENT_DEFINE("XXX");
  3. main()开头的准备工作 命令行、时间、打印信息等等
  4. 创建网络拓扑 附录1
  5. 安装TCP/IP协议族 附录2
  6. 安装应用程序 附录3
  7. 数据生成 本示例中未涉及
  8. 启动与结束 Run()和Destory()

附录1

网络拓扑=节点+信道
Node=节点
Channel=物理层信道协议
NetDevice=链路层信道协议,且NetDevice安装在Node里。

  • NetDevice和Channel基本上是一一对应的;
  • Node和NetDevice是一对多的。

就代码来看,创建网络拓扑经历三个步骤:

  1. NodeContainer创建节点。
  2. PointToPointHelper配置信道属性。
  3. 创建信道连接节点。调用PointToPointHelper::Install()创建两个PPP-NetDevice和一个PPP-Channel。

需要指出,助手类PointToPointHelper实际上完成了很多操作,如

  • node、channel、net_device之间关联关系的建立
  • net_device分配MAC地址
  • 为channel设置队列模型
  • ……

附录2

ns-3中的TCP/IP协议族主要包括传输层的TCP/UDP、网络层IP、ICMP等。
安装协议栈的助手类是InternetStackHelper,在安装完协议栈后还需要为net_device分配IP地址。代码中可以看到,设置IP地址用的是Ipv4AddressHelper,而将IP分配到net_device得到Ipv4InterfaceContainer。
Ipv4Interface的作用如下图所示,简单地说就是暴露给NetDevice,帮它保存IP地址。
image.png
Ipv4是网络层的类,IpL4Protocol是传输层TCP/UDP的基类。至此,节点已经在物理层到传输层都准备好。

附录3

应用层对应的C++类是Application,不同的Application对应不同的分组收发行为。示例代码中使用的UdpEcho应用比较简单,代码也很直观。
可能的疑惑是,为什么UdpEcho建立UDP连接不需要调用Socket的相关接口?
答案是,这些调用被封装在2个助手类UdpEchoServerHelper(bind、connect)和UdpEchoClientHelper(bind、recvfrom、sendto)里。

posted on   LeewayTang  阅读(124)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示