Intro
BG:
ns-3网络仿真工具是一个用于搭建网络拓扑,测试网络算法、模拟不同环境的网络性能的一套软件,这套软件由多个小模块构成(wifi ipv4之类的模块),运行时调用哪个就编译链接哪个。(这一段是我的理解)
NS2(Network Simulator, version 2)是一种面向对象的网络仿真器,本质上是一个离散事件模拟器。由UC Berkeley开发而成。它本身有一个虚拟时钟,所有的仿真都由离散事件驱动的。(这一段是百度百科)
ns-3提供了不少用于学习的小工程,都在ns-3.xx/example下,其中最基础的就是ns-3.xx/examples/tutorial中。tutorial,教程,顾名思义就是最基础的一些实例,看了就对ns-3的大致流程有了一定认知。
目前网上的一些解析,更多都是对大段的代码进行注释,且对网络拓扑没有详细分析,而本文将对third脚本进行代码全注释以及网络拓扑详细分析。
本文主要对third.cc脚本的内容进行解析,达到记录所学,帮助更多“入坑”ns-3的小伙伴,尤其是小白,更快入门的目的。
Method
阅读源码,参考周迪之所著的《开源网络模拟器ns-3 - 架构与实践》,阅读html对module和function的说明。
Result
先贴出来源码以及注释:
/* -*- 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
*/
#include "ns3/core-module.h"//ns-3核心
#include "ns3/point-to-point-module.h"//MAC层的点对点协议,与Ethernet、80211mac对应
#include "ns3/network-module.h"//tcp/IP+ethernet等网络协议栈
#include "ns3/applications-module.h"//http等应用层的东西
#include "ns3/mobility-module.h"//移动模型——wifi的STA移动的时候用的
#include "ns3/csma-module.h"//multiple access by carrier sensing,通过载波监听实现多条链路在同一个载波上通信
#include "ns3/internet-module.h"//TCP/IP
#include "ns3/yans-wifi-helper.h"//80211
#include "ns3/ssid.h"//80211关于SSID的部分
//#include "v4ping.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;//名字空间,不用 ns3:xxxx 了
NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");//允许用log系统中的宏定义打印信息
int
main (int argc, char *argv[])//主函数,.cc的都是c++,自然需要一个main函数
{
//如果不知道可以修改什么参数
//sudo ./waf --run "third --help"
//即可
//显示的都是后面addvalue里面的,想改就改
bool verbose = true;//是否显示执行过程,默认显示
uint32_t nCsma = 3;//csma节点的数目
uint32_t nWifi = 3;//wifi中STA的数目
bool tracing = false;//使能就生成wireshark文件(姑且就叫wireshark文件吧)
CommandLine cmd (__FILE__);//开始接受main的输入值
//获取标准输入值,赋值给相应变量,中间的简介在--help时打印出来
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);//把"nCsma"字符串在命令行里面的值,赋值给变量nCsma
//sudo ./waf --run "third --nCsma=5
cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);//把"nWifi"字符串在命令行里面的值,赋值给变量nWifi
cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);//把"verbose"字符串在命令行里面的值,赋值给变量verbose
cmd.AddValue ("tracing", "Enable pcap tracing", tracing);//把"tracing"字符串在命令行里面的值,赋值给变量tracing
//后面这三个的赋值和前面的一样,也可以同时多个值赋值
cmd.Parse (argc,argv);//如果不加这句最终确定,将不能获取std数据流
// The underlying restriction of 18 is due to the grid position
// allocator's configuration; the grid layout will exceed the
// bounding box if more than 18 nodes are provided.
if (nWifi > 18)//看看站点数目是不是过多
{
//要是设置太多直接退出并且报错
std::cout << "nWifi should be 18 or less; otherwise grid layout exceeds the bounding box" << std::endl;//报错
return 1;//退出,返回错误值
}
if (verbose)//日志是否显示
{
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);//UdpEchoClientApplication的log显示
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);//UdpEchoServerApplication的log显示
}
NodeContainer p2pNodes;//创建一组名字叫p2pNodes的节点,注意,叫p2p节点,但是现在和pointToPoint协议暂时没有任何关系
p2pNodes.Create (2);//p2pNodes有两个
PointToPointHelper pointToPoint;//创建一个pointToPoint协议的信道,包括MAC(P2P只有MAC)和相应的PHY——毕竟是helper,都给你安排上了
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));//信道的传输速率是5Mbps
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));//信道延迟是2ms
NetDeviceContainer p2pDevices;//创建一组名字叫p2pDevices的网络设备(网络设备相当于MAC层协议)
p2pDevices = pointToPoint.Install (p2pNodes);//给p2pNodes这两个节点都安装上pointToPoint协议device——p2pDevices,这俩节点也用5Mbps、2ms的物理信道相连
NodeContainer csmaNodes;//创建一组名字叫csmaNodes的节点
csmaNodes.Add (p2pNodes.Get (1));//这一组csmaNodes每个都与p2pNodes中的第二个节点是同一个节点
csmaNodes.Create (nCsma);//这组csmaNodes节点总共有nCsma个
CsmaHelper csma;//创建一个csma协议的信道,
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));//信道的传输速率是100Mbps
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));//信道延迟是6.56us
NetDeviceContainer csmaDevices;//创建一组名字叫csmaDevices的网络设备
csmaDevices = csma.Install (csmaNodes);//给csmaNodes这nCsma个节点都安装上csma协议device——csmaDevices,节点用100Mbps、6.56us的物理信道相连
NodeContainer wifiStaNodes;//创建wifi站点节点
wifiStaNodes.Create (nWifi);//节点总共有 nWifi 个
NodeContainer wifiApNode = p2pNodes.Get (0);//给安装过PtpP net device的p2pnode0重命名,叫做AP node
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();//传播延迟模型、损耗模型配置
YansWifiPhyHelper phy;//误码率模型配置
phy.SetChannel (channel.Create ());//一个带误码率的、延迟和损耗的信道
WifiHelper wifi;//设置一个速率控制算法(一个wifi net device的选项之一)
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");//速率控制算法为“AARF速率控制算法”
WifiMacHelper mac;//wifi 的 mac类
Ssid ssid = Ssid ("ns-3-ssid");//设置AP的ssid
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));//设置mac为STA的mac,ssid就是ns-3-ssid,积极探测为0(为1就会使得运行结果后三行消失不见)
NetDeviceContainer staDevices;//创建一堆NetDevice,专门给wifiStaNodes准备
staDevices = wifi.Install (phy, mac, wifiStaNodes);//给这些NetDevice安排上速率控制算法、连接上一个带误码率的、延迟和损耗的信道,并且放到每一个wifiStaNodes里面
mac.SetType ("ns3::ApWifiMac","Ssid", SsidValue (ssid));//给AP设置上AP ssid
NetDeviceContainer apDevices;//创建一堆NetDevice,专门给wifiApNode准备(其实准备一个就行了)
apDevices = wifi.Install (phy, mac, wifiApNode);//给这些NetDevice安排上速率控制算法、连接上一个带误码率的、延迟和损耗的信道,并且放到唯一一个wifiApNode里面
代码的整体来看,不同的helper完成的功能不同,下面将对比CsmaHelper、PointToPointHelper和WiFi有关的helper:
- CsmaHelper:创建一个信道,有延迟;创建一个MAC+PHY,有速率
- PointToPointHelper:创建一个信道,有延迟;创建一个MAC+PHY,有速率
- WifiHelper:配置一个速率控制算法——包括AP和STA,同时负责把配置好的mac和phy给wifi添加上
- YansWifiChannelHelper:信道参数,包括延迟损耗误码率啥的,总结在一个phy对象(结构体)里面,配合wifihelper使用
- WifiMacHelper:媒体接入层的参数配置,包括SSID、积极探测功能,并总结到一个mac对象(结构体)里面,配合wifihelper使用
可见,对于简单的协议,MAC和PHY的参数都在一个helper里面配置就好,对于相对复杂的WIFI(802.11)协议,参数分开配置
以下第一张图是各个节点组里面各自包括哪些节点——可见怕p2pnodes组里面的两个节点在WIFI侧与csma侧都有“客串”:
下图是各个节点的连接方式,p2p是有线连接,协议是Pointtopoint;csma也是有线连接,协议是csma;wifi节点分为AP和sta,sta无线与AP连接,AP本身与p2p节点就是同一个节点。
内容太多,下一个部分留待《ns-3.35_third.cc_ns-3网络仿真工具wifi脚本解析_wifi脚本网络拓扑_ns-3third脚本全注释_新手ns-3_ns-3入门_ns-3third脚本解析_Part2》继续写。