关键概念

出处:http://blog.csdn.net/hhhparty/article/details/76170079


今天从《ns-3 tutorial》第4章开始。

4. 基本概念

在看或写ns-3程序前,需要理解掌握一些概念和抽象问题。 
It’s be recommended taking the time to read through this section just to ensure you’re starting on a firm foundation.

4.1 关键概念(Key Abstractions)

先介绍几个网络中常用的词,它们在NS3中有特定含义。 
1.node(节点) 
NS3不局限于Internet模拟,所以用node表示网络中的主机或终端,而不是直接用host。node与图论中的“点”概念类似。NS-3中把基本计算设备都称为node,并将这个抽象概念用C++类Node描述。Node类中有一些管理计算设备行为的方法和属性。 
你可能已经开始考虑怎么给Node上应用、协议栈、外设了,以便这个设备能有效工作,但这是稍后才能考虑的事,但都是基于node模型展开的。 
2.Application(应用) 
计算机软件通常划分为:系统软件和应用软件。两者直接的切分线往往是基于系统特权级别的变化。在NS-3中没有OS的概念,也没有特权级别或系统调用的概念,但有Application应用程序的概念。就像真实世界里运行于计算机中的应用程序执行某个任务一样,在模拟世界中运行于NS3 Nodes上的Applications也执行某个模拟。 
NS-3里,一个能产生某项模拟活动的用户程序就被抽象地称为Application。这个抽象被C++类Application所描述。Application类中包含了一些用户级操作以执行模拟活动。在本文中,我们使用特殊的Application类——UdpEchoClientApplication和UdpEchoServerApplication类,构成一个C/S模拟网络。 
3.Channel(信道) 
传递数据的网络媒介(线缆/无线频道等)被称为channels。在NS-3中,连接一个node到一个通信信道,就像你在现实中把电脑后的网线连到墙上以太网插槽中一样。NS-3中把基本的通信子网(就是物理层与链路层)抽象为Channel,并用C++类Channel描述。 
Channel类里提供了一系列方法,用于管理通信子网对象和连接节点。用户可以根据基本的Channel类编写自己特定Channel类,例如某线缆。特定的Channel也可以是大的以太交换机或用于无线网络的充满障碍的三维信道空间。 
本文中使用特定的Channel类CsmaChannel、PointToPointChannel和WiFiChannel,也就是典型的使用以太技术的动态接入共享信道、点对点信道、wifi信道。 
4.NET Device(网络设备) 
通常连接一台主机到网络,我们需要买网线和网卡(NICs),网卡这类设备称为device,device需要在驱动driver支持下工作。在NS-3中,net device这个概念包含了软件dirver和硬件device。一个net device安装在Node上,使Node可以经由Channel与别的Node通信。 
NS3中Net Device被抽象描述为C++类NetDevice,它提供了一些方法来管理Node对象与Channel对象的连接。 
本文中将使用特殊的网络设备类CsmaNetDevice,PointToPointNetDevice和WifiNetDevice(即以太网卡类/点到点网卡类/wifi网卡类)。 
5.Topology Helpers(拓扑工具) 
真实世界里主机中安装着网络设备,NS-3中,node连接着net device。在较大的网络模拟中,可能需要安排Nodes、Netdevices和Channels的许多连接,这个时候需要拓扑工具来规划网络形态。 
在NS-3中,连接node与netdevice、netdevice与channel、指定IP地址等工作,需要调用拓扑工具topology helpers,这会使任务变得简单。例如:生成网络设备、增加MAC地址、安装设备到node,配置node协议栈,连接netdevice到信道等等。

补充一句,上述C++类在ns-allinone-3.26/ns-3.26/src/network/model中。

4.2 第一个NS-3脚本

下载ns-allinone-3.26之后,你会在ns-3.26中看到如下内容: 
这里写图片描述

切换工作环境到examples/tutorial中,你会看到一个叫first.cc的文件。这个文件是一个简单的p2p网络模拟程序,它连接两个nodes,并在节点间发送一个数据包(echo)。下面我们逐行学一下first.cc

/* -*- 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"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

int
main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);

  Time::SetResolution (Time::NS);
  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

  NodeContainer nodes;
  nodes.Create (2);

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

  NetDeviceContainer devices;
  devices = pointToPoint.Install (nodes);

  InternetStackHelper stack;
  stack.Install (nodes);

  Ipv4AddressHelper address;
  address.SetBase ("10.1.1.0", "255.255.255.0");

  Ipv4InterfaceContainer interfaces = address.Assign (devices);

  UdpEchoServerHelper echoServer (9);

  ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
  serverApps.Start (Seconds (1.0));
  serverApps.Stop (Seconds (10.0));

  UdpEchoClientHelper echoClient (interfaces.GetAddress (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 (10.0));

  Simulator::Run ();
  Simulator::Destroy ();
  return 0;
}
 
 
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

1.程序模板(Boilerplate) 
第1行是个emacs风格行,告诉emacs格式转换等编码风格方面的信息, 
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
如果你要参与开发NS-3,那就得遵循相关编码风格规范(具体在doc/codingstd.txt中)。建议在所有NS-3程序中都这么写,特别是使用emacs编辑器的。 
第2~15行是NS-3采用的GNU General Public License的相关说明。 
2.模块引用 
第17-21行,是C++引用其他模块的include语句,说明first.cc中会用到这些库:core-module、network-module、Internet-module、point-to-point-module、Application-module。引用了这些已有的库,有利于我们快速构建自己的程序,不必重新发明轮子。这些头文件放在build/ns3/下,如果我们打开上述之一network-module.h看一看,会看到这样的内容:

#ifdef NS3_MODULE_COMPILATION
# error "Do not include ns3 module aggregator headers from other modules; these 
are meant only for end user scripts."
#endif
#ifndef NS3_MODULE_NETWORK  
// Module headers:
#include "address-utils.h"
#include "address.h"
#include "application-container.h"
#include "application.h"
#include "ascii-file.h"
#include "ascii-test.h"
#include "buffer.h"
#include "byte-tag-list.h"
#include "channel-list.h"
#include "channel.h"
#include "chunk.h"
#include "crc32.h"
#include "data-rate.h"
......
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

说明这个头文件包含了许多具体的网络相关头文件,这并不是说first.cc会使用所有的库,只是为了写程序方面,虽然不太经济。

  • core-module.h包含了src/core中的所有头文件;
  • network-module.h包含了src/network中的所有头文件
  • Internet-module.h包含了src/Internet中的所有头文件
  • point-to-point-module.h包含了src/point-to-point中的所有头文件
  • application-module.h包含了src/Application中的所有头文件 
    编译后,这些头文件会被放到build/ns3或build/debug或build/optimized目录中,具体在哪取决于版本和你的配置,我这里都在build/ns3中。

3.NS3命名空间 
第23行声明使用ns3为命名空间。NS-3的程序都在这个空间内。这个ns3空间与全局命名空间彼此分开,有助于同其他代码进行整合。这里使用using语句将ns3引入当前全局声明域内。 
4.日志 
第25行设置了日志文件参数。NS_LOG_COMPONENT_DEFINE (“×××”)设置了相关参数,ns3将创建一个名为FirstScriptExample的日志组件,来记录控制台消息。 
5.主函数 
从27行到最后,都是主函数内容了。

int main (int argc, char *argv[])声明了函数 
Time::SetResolution (Time::NS);设置了SetResolution(计时精度)为纳秒,纳秒是NS3中最小的计时单位,可以改变该设置为大一些的计时单位。如果不设置,则默认为纳秒。

接下来两行脚本开启了两个日志组件,分别建在Echo client和Echo Server application中:

LogComponentEnable(“UdpEchoClientApplication”, LOG_LEVEL_INFO); 
LogComponentEnable(“UdpEchoServerApplication”, LOG_LEVEL_INFO);

6.拓扑工具 
下面的两行用于生成ns-3 node对象,代表了本次模拟的计算机。

NodeContainer nodes; 
nodes.Create (2);

(1)NodeContainer类是一个拓扑工具类,它提供了一种方便的生成、管理和访问node对象的方法。上面第一句是声明一个NodeContainer对象nodes,然后用其creat方法生成两个node对象。现在这些node还不能工作,我们需要将它们连成一个网络,最简单的网络就是两台机器组成的点对点网。

(2)PointToPointHelper类也是一个拓扑工具类,它用于构建一个点对点网络。回忆一下net device和Channel的概念,在这里我们需要使用点对点的net device和Channel。定义如下:

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

属性DataRate是 PointToPointNetDevice 对象中的属性,可以在帮助中查到,除此以外,还有多个设备属性可以设置。例如:Mac48Address 、Ptr< PointToPointChannel >、Ptr< Packet >、Ptr< Node >等很多。

(3)NetDeviceContainer是其中第三个拓扑工具类。它的对象用于管理网络设备,这些网络设备由PointToPointHelper对象生成、配置和安装(安装到node上)。

NetDeviceContainer devices; 
devices = pointToPoint.Install (nodes); //这个方法以NodeContainer对象为参数,对于NodContainer对象nodes包含的每个node,一个点对点网络设备被生成且保存于NetDeviceContainer对象devices中。一个PointToPointChannel对象被生成,且两个PointToPointDevices被连接起来。

在pointToPoint.Install()方法被执行后,我们将有两个节点,每一个都安装了点到点网卡和连接他们的一条点到点信道,设备和信道将使用上文配置的参数配置。 
(4)InternetStackHelper是用于方便安装和配置管理Internet协议栈的工具类。

InternetStackHelper stack; 
stack.Install (nodes);//执行后,含有TCP、IP、UDP等协议的Internet stack将安装到nodes中的每个node上。

(5)Ipv4AddressHelper是一个帮助我们设置IP地址的工具类。

Ipv4AddressHelper address; 
address.SetBase (“10.1.1.0”, “255.255.255.0”);//设置了一个ip网络号和子网掩码,意味着这个网络的ip地址从10.1.1.0~10.1.1.255.

ns3的底层实现会记录所有已经分配的ip地址,如果出现重复生成同样的ip地址段(使用setbase方法),就会报告一个fatal error,这个错将很难调试发现。 
(6)Ipv4InterfaceContainer是一个用于分配和管理ip地址的工具类。Ipv4AddressHelper的对象address将ip地址分配给Devices,这些已分配地址的接口们可交给Ipv4InterfaceContainer对象管理。这有利于在需要列出所有接口时,统一调用。

Ipv4InterfaceContainer interfaces = address.Assign (devices);//实现ip地址的分配,devices中的device们,将按递增顺序获得ip地址和子网掩码,从10.1.1.1到10.1.1.2

7.应用程序(Application) 
在本程序中使用了两个特殊的Application类:UdpEchoServerApplication和UdpEchoClientApplication。在管理和配置Application时,还是用工具类来实现,这里有两个工具类:UdpEchoServerHelper and UdpEchoClientHelper。应用程序的工具类不是应用本身,只是帮助我们生成具体应用的。

UdpEchoServerHelper echoServer (9);//设置了端口号为9的应用程序echoServer 
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));//将echoServer这个程序安装到一个node上。这个install方法也是以NodeContainer对象为参数的。 
serverApps.Start (Seconds (1.0));//程序要设置一个启动时间,生成网络流量。NS3中的时间对象使用Seconds对象。 
serverApps.Stop (Seconds (10.0));//程序可以设置一个停止时间,结束生成网络流量

UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);//生成echoClient应用,并设置了两个属性:RemoteAddress=interfaces.GetAddress (1),即10.1.1.1,RemotePort=9 
echoClient.SetAttribute (“MaxPackets”, UintegerValue (1));//设置了client在模拟中,发送数据包最多为1个 
echoClient.SetAttribute (“Interval”, TimeValue (Seconds (1.0)));//设置Interval,数据包发送的时间间隔为1秒 
echoClient.SetAttribute (“PacketSize”, UintegerValue (1024));//设置包的大小为1024字节。 
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));//将应用echoClient安装到节点上,同时建立clientApps管理所有客户端应用程序。

上面对于echo client程序设置了5个属性:“RemoteAddress” 、“RemotePort”、 “MaxPackets”、 “Interval”、”PacketSize”。 
8.模拟器 
设置完nodes、net devices、channels、applications、protocols等之后,下面启动模拟。 
之前已经设置了应用程序的启动特性:

serverApps.Start (Seconds (1.0));//在第1秒启动服务器端所有程序 
serverApps.Stop (Seconds (10.0));//在第10秒关闭服务器所有程序 
clientApps.Start (Seconds (2.0));//在第2秒启动客户端所有程序 
clientApps.Stop (Seconds (10.0));//在第10秒关闭客户端所有程序

之后运行run方法,执行模拟。根据程序中的调度,第1秒执行服务器应用echoServer,第2秒客户端程序echoClient启动,发出一个数据包,到第10秒两个程序结束运行。模拟运行完毕后执行destroy方法结束模拟。

Simulator::Run (); 
Simulator::Destroy ();

ns-3是一个离散事件模拟器,每个事件与它执行的时间相联系,模拟过程以时间为序依次执行各个事件。当某个事件执行时,他可能生成0 、1或多个其他事件。当所有事件都按顺序执行完毕时,模拟过程将自动停止,或者在事件执行中如有Stop事件(Simulator:Stop(stopTime))出现,模拟过程也会停下来。一些事件是无限循环的,例如FlowMonitor、RIPng、RealtimeSimulator等,这些事件需要使用Stop停止。

9.编译你的脚本 
当写完脚本的源代码后,可以把脚本放到scratch目录中,之后运行waf命令就可以自动编译了。例如将 examples/tutorial/first.cc拷贝到scratch中,改名为myfirst.cc,然后回到ns-3.26工作目录下,执行waf: 
这里写图片描述 
可以看到,build finished successfully。之后,运行myfirst模拟程序: 
命令为./waf –run scracth/myfirst 
这里写图片描述

4.3 NS-3源代码

想看NS-3源代码可以使用Mercurial下载最新的,或看网站http://code.nsnam.org/ns-3-dev

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值