用NS3进行虚拟仿真

一.下载虚拟机

直接下载虚拟机的安装包,然后分配内存等一系列操作,后注册用户

二.安装NS3虚拟仿真软件

1.在网上下ns3软件的安装包

(1)第一种方式

  • 给出ns3官方网址:
    https://www.nsnam.org/
  • 给出安装包的网址:
    https://www.nsnam.org/release/ns-allinone-3.15.tar.bz2
    将下载的软件压缩包放入虚拟机的共享文件夹中
    在虚拟机中打开共享文件夹
    图1
  • 将压缩包复制到usr目录下


    图2

    (2)第二种方式

  • 创建新目录用于存放ns3安装包
    mkdir ns3
    创建一个名为ns3的目录
  • 进入到ns3目录下
    cd /ns3
  • 直接从网络上下载ns3安装包并保存在当前目录
    wget https://www.nsnam.org/release/ns-allinone-3.15.tar.bz2
2.解压压缩包
  • sudo tar -jxvf ns-allinone-3.29.tar.bz2
    输入用户密码


    图1

    图2
3.将解压后的安装包进行更名
  • sudo mv ns-allinone-3.29 ns3


    图3

三.编译ns3软件包

1.使用build.py编译

第一次编译NS3软件包,建议用./build.py --enable-examples--enable-tests命令,对下载的源代码进行整体编译。

  • 进入到ns3目录下
    cd ns3


    图3
  • 敲入如下命令,编译脚本开始编译,初次编译用时较长,请耐心等待
  • ./build.py --enable-examples --enable-tests
    如果敲入这个代码出现:


    图4

    这个提示,则是因为你虚拟机里没有python2
    那么就要装python2

  • python2 的安装:
    1.首先查看一下 /usr/bin/ 文件夹里面有没有python文件
    sudo apt-get install python
    遇到[Y/N]的时候输入Y就可以


    图片5

    2.如果有这个文件则执行下面这句话
    sudo apt-get --reinstall install python-minimal

这个时候你输入上面代码,又可能编译成功有可能编译不成功,如果安装了gcc和g++则会编译成功,如果不成功那么则需要安装gcc和g++。

  • gcc的安装:


    图6

    安装完以后在进入usr/bin中查看是否有gcc
    如果存在gcc则进行上一步继续输入:

  • ./build.py
    如果编译成功则出现如下内容:


    编译成功

    输入:

  • ./build.py --enable-examples --enable-tests
    则出现


    图1
  • 编译完成之后,在当前目录ns3下会产生一个名为ns-3.29/的目录,切换到该目录下
    cd ns-3.29


    图2
2.使用waf编译

NS3的编译系统采用了Waf。它是用Python开发的新一代编译管理系统。
更多关于Waf的细节,可以通过:http://code.google.com/p/waf/ 网址获取。
使用waf对NS3源代码进行编译时,可以分为优化编译和调试编译两种情况。默认情况将进行调试编译。
为了通知waf进行优化编译,进行如下步骤

  • 为防止重复编译可能带来的错误,第一条命令首先清空以前编译的内容(编译过的内容位于ns-3.29/build/目录下)
    sudo ./waf clean


    图3

该命令不是必须的,但这样做是一个好的习惯。

  • 第二条命令,编译系统开始检查各种依存关系,并进行编译。配置NS3,“–build-profile=debug”是让NS3以debug模式运行,可以在运行时查看日志信息,方便调试
    sudo ./waf --build-profile=debug --enable-examples --enable-tests configure
    你可以看到类似如下的输出:


    结果1

    结果2

    说明配置成功。

  • 然后接着编译
    sudo ./waf


    结果1

    结果2

此外可以通过参数-o,更改编译的目标目录,默认编译目录为build/。可以通过如下命令,更改编译的目标目录为build/debug/

  • ./waf -d debug -o build/debug --enable-examples --enable-testsconfigure

在waf中还有许多其它的配置和编译选项可用。可以通过以下命令察看更多的选项:

  • ./waf --help

三.对编译的正确性进行测试

  • 通过运行“./test.py -c core”脚本进行ns-3软件包的正确性测试
    sudo ./test.py -c core
    输入用户密码


    开始编译

    成功

    用户通常可以运行此命令来检查NS3软件包是否正确编译了。

四.运行第一个脚本

我们通常使用waf运行脚本程序。在正确编译了NS3软件包之后,如果要运行一个程序,只需在waf后加入--run选项即可。
那第一个就运行常见的HelloSimulator程序,该程序就相当于学习一门语言时的Hello World程序:

  • sudo ./waf --run hello-simulator


    结果

    出现HelloSimulator则说明编译成功。
    如果没有看到输出“HelloSimulator”,说明你是在优化编译模式下进行的编译,在优化编译模式下,默认将关闭控制台输出。可以通过以下命令:

  • sudo ./waf clean
  • sudo ./waf -d debug --enable-examples --enable-tests configure
    在调试编译模式下进行重新编译。

五.NS3中的几个关键概念:

(以下内容部分来自于百度百科)

1.节点Node

在网络术语中,任何一台连接到网络的计算设备被称为主机,亦称为终端。NS3是一个网络模拟器,而非一个专门的因特网模拟器,为此我们避开术语“主机”,因为这个词太容易让人联想到因特网和及其相关协议。因此,我们选用了一个来源于图论,在其他网络模拟器中亦广泛使用的术语:节点。
NS3中基本计算设备被抽象为节点。节点由用C++编写的Node类来描述。Node类提供了用于管理计算设备的各种方法。
可以将节点设想为一台可以添加各种功能的计算机。为了使一台计算机有效地工作,我们可以给它添加应用程序,协议栈,外设卡及驱动程序等。NS3采用了与此相同的模型。

2.信道

在NS3中,可以把节点连接到代表数据交换信道的对象上。在这里,基本的通信子网这一抽象概念被称为信道,用C++编写的Channel类来描述。
Channel类提供了管理通信子网对象和把节点连接至信道的各种方法。信道类同样可以由开发者以面向对象的方法自定义。一个信道实例可以模拟一条简单的线缆(wire),也可以模拟一个复杂的巨型以太网交换机,甚至无线网络中充满障碍物的三维空间。
信道模型的实例包括:CsmaChannel,PointToPointChannel和WifiChannel。举例来说,CsmaChannel信道模拟了用于一个可以实现载波侦听多路访问的信道,这个信道具有和以太网相似的功能。

3.网络设置

在Unix/Linux系统中,外围硬件被划为“设备”。设备通过驱动程序来控制,而网卡通过网卡驱动程序来控制。在Unix/Linux系统中,网卡被称为像eth0这样的名字。
在NS3中,网络设备这一抽象概念相当于硬件设备和软件驱动的总和。NS3仿真环境中,网络设备相当于安装在节点上,使得节点通过信道和其他节点通信。像真实的计算机一样,一个节点可以通过多个网络设备同时连接到多条信道上。
网络设备由用C++编写的NetDevice类来描述。NetDevice类提供了管理连接其他节点和信道对象的各种方法,并且允许开发者以面向对象的方法来自定义。
几个特定的网络设备的实例,它们分别是CsmaNetDevice,PointToPointNetDevice, 和WifiNetDevice。正如以太网卡被设计成在以太网中工作一样,CsmaNetDevice被设计成在csma信道中工作,而PointToPointNetDevice在PointToPoint信道中工作,WifiNetNevice在wifi信道中工作。

4.应用程序

在NS3中并没有真正的操作系统的概念,更没有特权级别或者系统调用的概念。NS3仿真环境中的应用程序在节点上运行来驱动模拟过程。
在NS3中,需要被仿真的用户程序被抽象为应用。用Application类来描述。这个类提供了管理仿真过程中用户层应用的各种方法。开发者应当用面向对象的方法自定义和创建新的应用。
在这里我们会使用Application类的两个实例:UdpEchoClientApplication和UdpEchoServerApplication。这些应用程序包含了一个client应用和一个server应用来发送和回应仿真网络中的数据包。

六.分析例子程序first.cc的源代码

-cd /usr/ns3/ns-3.29/examples/tutorial/
进入上面这个目录下会发现里面有一个first.cc文件
这一个脚本会在两个节点间创建一个简单的点到点的连接,并且在这两个节点之间传送一个数据包


目录

以下是first.cc文件的源代码以及详细解析:

//emacs模式行
/* -*- Mode:C++; c-file-style:''gnu''; indent-tabs-mode:nil; -*- */

//include文件在build/ns3目录下
//编译时Waf会根据配置把在ns3目录下的公共的头文件放到build/debug或者build/optimized目录下
#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;

//日志,声明了一个叫FirstScriptExample的日志组件,通过引用FirstScriptExample这个名字的操作,可以实现打开或者关闭控制台日志的输出
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

//主函数声明
int main (int argc, char *argv[])

{
//用来使两个日志组件生效的。它们被内建在Echo Client 和EchoServer 应用中
LogComponentEnable ("UdpEchoClientApplication",LOG_LEVEL_INFO);

LogComponentEnable ("UdpEchoServerApplication",LOG_LEVEL_INFO);




//1.创建节点
//声明了一个名为”nodes”的NodeContainer
NodeContainer nodes;
//调用了nodes对象的Create()方法创建了2个节点。
nodes.Create (2);
//pointToPointHelper来做关于创建,配置和安装设备的工作。
// 拓扑辅助工具的helper类,使用了PointToPointHelper来配置和连接网络设备PointToPointNetDevice和信道PointToPointChannel对象。
//在栈中初始化了一个PointToPointHelper的对象pointToPoint
PointToPointHelper pointToPoint;
//PointToPointHelper对象当创建一个PointToPointNetDevice对象时使用“5Mbps"来作为数据速率。
pointToPoint.SetDeviceAttribute ("DataRate", StringValue("5Mbps"));
//PointToPointHelper使用"2ms"(2毫秒)作为每一个被创建的点到点信道传输延时值
pointToPoint.SetChannelAttribute ("Delay", StringValue("2ms"));




//2.利用拓扑设置链路
//使用一个NetDeviceContainer对象来存放需要所有被创建的NetDevice对象
NetDeviceContainer devices;
//PointToPointHelper的Install()方法以一个NodeContainer对象作为一个参数。
//在Install()方法内,一个NetDeviceContainer被创建了。
//对于在NodeContainer对象中的每一个节点(对于一个点到点链路必须明确有两个节点),
//都将有一个PointToPointNetDevice被创建和保存在设备容器内,有一个PointToPointChannel对象被创建,两个PointToPointNetDevices与之连接。
//当PointToPointHelper对象创建时,那些在helper中被预先设置的属性被用来初始化对象对应的属性值。
devices = pointToPoint.Install (nodes);
//当调用了pointToPoint.Install(nodes)后,我们会有两个节点,每一个节点安装了点到点网络设备,在它们之间是一个点到点信道。
//两个设备会被配置在一个有2ms传输延时的信道上以5Mbps的速率传输数据。



//3.安装协议栈
InternetStackHelper stack;
//类InternetStackHelper是一个辅助安装网络协议栈的helper类。
//其中Install()方法以NodeContainer对象作为参数,当它被执行后,它会为节点容器中的每一个节点安装一个网络协议栈(TCP,UDP,IP等)
stack.Install (nodes);





//4.分配IP地址
Ipv4AddressHelper address;
//从10.1.1.0开始以子网掩码为255.255.255.0分配地址
address.SetBase ("10.1.1.0", "255.255.255.0");


//使用Ipv4Interface对象将一个IP地址同一个网络设备关联起来
Ipv4InterfaceContainer interfaces = address.Assign(devices);


//声明了UdpEchoServerHelper,用来帮助创建真正应用的helper对象
//我们约定在helper类的对象中放置必需的属性,除非我们告知helper对象服务器和客户端所共知的一个端口号,否则这个helper对象是不会起任何作用的
UdpEchoServerHelper echoServer (9);


//Install()方法的执行,才初始化回显服务器的应用,并将应用连接到一个节点上去
//这里有一个C++隐式转换,此转换以nodes.Get(1)的结果作为输入,并把它作为一个NodeContainer的构造函数的参数,最终这个新构造的NodeContainer被送入Install方法中去
//echoServer.Install将会在管理节点的NodeContainer容器索引号为1的机节点上安装一个UdpEchoServerApplication。安装会返回一个容器,这个容器中包含了指向所有被helper对象创建的应用指针
//传递了double类型对象1.0到Seconds的一个方法,通过seconds()方法,把它转换到ns-3的Time对象
ApplicationContainer serverApps = echoServer.Install (nodes.Get(1));

serverApps.Start (Seconds (1.0));
//使echo服务应用在1s时开始(生效)并在10s时停止(失效)
serverApps.Stop (Seconds (10.0));


//创建了一个UdpEchoClientHelper的对象,并告诉它设置客户端的远端地址为服务器节点的IP地址。
//我们同样告诉它准备发送数据包到端口9
UdpEchoClientHelper echoClient (interfaces.GetAddress (1),9);
//“MaxPackets”属性告诉客户端我们所允许它在模拟期间所能发送的最大数据包个数。
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
//“Interval”属性告诉客户端在两个数据包之间要等待多长时间。
echoClient.SetAttribute ("Interval", TimeValue (Seconds(1.0)));
//“PacketSize”属性告诉客户端它的数据包应该承载多少数据。
echoClient.SetAttribute ("PacketSize", UintegerValue(1024));

//停止echo服务端
//正如echo服务端一样,我们告诉echo客户端何时来开始和停止,
//这里我们使客户端在模拟器中时间为2s的时候开始(即服务端生效1s后才开始)。
ApplicationContainer clientApps = echoClient.Install (nodes.Get(0));






//5.运行模拟器
clientApps.Start (Seconds (2.0));
//实际上我们是在模拟器中1.0s,2.0s,和10.0s时预设了时间的发生
//当Simulator::Run被调用时,系统会开始遍历预设事件的列表并执行。
//首先它会在1.0s时运行事件,这个事件会使echo服务端应用生效(这个事件会预设更多的其他事件)
//接下来仿真器会运行在t=2.0s时的事件,即让echo客户端应用开始

clientApps.Stop (Seconds (10.0));


//当这些事件被执行后,就没有将来的事件来执行了,函数Simulator::Run会返回。整个模拟过程就结束了
Simulator::Run ();
//该方法被执行后,模拟器中所有创建的对象将被销毁。你自己并不需要追踪任何对象,你所需要做的仅仅是调用Simulator::Destroy并且退出
Simulator::Destroy ();

return 0;

}

看完这个我相信你会对编写网络仿真脚本的基本流程有了一定的了解。

  • NS3 仿真基本流程:

(部分来自于百度博客)

1.选择或开发相应的模块

根据实际仿真对象和仿真场景选择相应的仿真模块:如果是有线局域网络(CSMA)还是无线局域网络(Wi-Fi);节点是否需要移动(mobility);使用何种应用程序(application);是否需要能量(energy)管理;使用何种路由协议(internet、aodv等);是否需要动画演示等可视化界面(visualizer、netanim)等。如果要搭建的网络是比较新的网络,如延迟容忍网络(DTN)等,需要开发设计协议,如路由协议、移动模型、能量管理模型等。

2.编写网络仿真脚本

有了相应的模块,就可以搭建网络仿真环境,ns3仿真脚本支持两种语言:C++和Python,但是两种语言的API接口是一样的,部分API可能还没有提供Python接口。编写ns3仿真脚本的大体过程如下:
(1)生成节点:
ns3中节点相当于一个空的计算机外壳,接下来要给这个计算机安装网络所需要的软硬件,如网卡、应用程序、协议栈等。
(2)安装网络设备:
不同的网络类型有不同的网络设备,从而提供不同的信道、物理层和MAC层,如CSMA、WiFi、WiMAX和point-to-point等。
(3)安装协议栈:
ns3网络中一般是TCP/IP协议栈,依据网络选择具体协议栈,如是UDP还是TCP,选择何种不同的路由协议(OLSR、AODV和Global等)并为其配置相应的IP地址,ns3即支持IPv4也支持IPv6。
(4)安装应用层协议:
依据选择的传输层协议选择相应的应用层协议,但有时需要自己编写应用层产生网络数据流量的代码。
(5)其他配置:
如节点是否移动,是否需要能量管理等。
(6)启动仿真:
整个网络场景配置完毕,启动仿真。

3.仿真结果分析

仿真结果一般有两种,一种是网络场景,如节点拓扑结构,移动模型等,一般可以通过可视化界面(pyviz或NetAnim)可以直接观测到。另一种是网络数据,它除了可以在可视化界面下进行简单统计,也可以通过专门的统计框架(stats)或者通过ns-3提供的追踪(tracing)系统收集,统计和分析相应的网络数据,如数据分组的延迟、网络流量、分组丢失率等。

4.依据仿真结果调整网络配置参数或修改源代码

有时实际结果与预期相差较大,这时就需要分析原因(是网络参数有问题还是协议本身有问题),然后重新设计,仿真,直到达到满意的结果。

  • 运行first.cc脚本程序

要运行脚本时,只需将脚本放到scratch目录下,并运行waf,这样脚本就会被编译。

  • sudo cp first.cc /usr/ns3/ns-3.29/scratch/


    步骤1

    将first.cc文件进行更名,更名为myfirst.cc文件

  • sudo mv first.cc myfirst.cc


    步骤2

    使用waf命令来编译自己的第一个实例脚本:

  • cd ..
  • sudo ./waf


    示例1

    示例2
  • sudo ./waf --run scratch/myfirst
    可以看到编译系统先检查文件被编译了,接着运行了它。


    结果

    上面的四行白色的结果表示的意思是:
    第一行:客户机在2秒的时候向IP为10.1.1.2的节点的第九号端口(port)发送了1024字节大小的数据包。
    第二行:10.1.1.2的这个服务器在2.00369秒的时候收到了来自10.1.1.1的端口为49153的1024字节大小的数据包。
    第三行:10.1.1.2的服务器在2.00369秒向10.1.1.1的49153号端口发送了1024字节的一个数据包。
    第四行:2.00737秒客户机(10.1.1.1)接到了来自10.1.1.2(服务器)的9号端口的一个1024字节的数据包。

七.打开仿真界面

要想使自己写的程序可视化,一共有两种方式:

1.Pyiz

(我还没有试过这种方法所以有部分知识来自于百度百科,我也不知道好不好使你们可以试试)
PyViz工具使用参考网址:http://www.nsnam.org/wiki/index.php/PyViz

1.安装依赖包
  • sudo apt-get install python-dev python-pygraphviz python-kiwi python-pygoocanvas python-gnome2 python-gnomedesktop python-rsvg
    注意: ‘python-gnomedesktop’安装包问题 将命令python-gnomedesktop换为 python-gnome2-desktop-dev
2.安装交互python使得GUI上有控制台按钮
  • sudo apt-get install ipython
3.PyViz测试

(1) python脚本

  • sudo ./waf --pyrun src/flow-monitor/examples/wifi-olsr-flowmon.py --visualize

(2) C++脚本
对于src/olsr/examples/simple-point-to-point-olsr.cc脚本,要出现GUI界面,使用下面的命名是无法成功的

  • sudo ./waf --run src/olsr/examples/simple-point-to-point-olsr --vis
    需要修改wscript文件obj=bld.create_ns3_program('simple-point-to-point-olsr', ['point-to-point', 'internet', 'olsr', 'applications', 'wifi'])
    修改成
    obj=bld.create_ns3_program('simple-point-to-point-olsr', ['point-to-point', 'internet', 'olsr', 'applications', 'wifi', 'visualizer'])
4.使用方法

以命令行参数的形式调用,只要编写的脚本(形如xxx.cc文件)中加入下面的语句(需加在创建节点之前):
1)CommandLine cmd;
2)cmd.Parse (argc, argv);
运行程序时加入参数 --vis
比如:sudo ./waf --run examples/tutorial/third --vis

5.注意:--vis 选项无效

visualizer模块依赖PythonBinding,NS3中的PythonBinding由pybindgen完成,但是pybindgen工具在ns-allinone-3.xx目录下,而不是在ns-3.xx目录下,如果移动了ns-3.xx的目录,就无法定位pybindgen进而完成PythonBinding
解决方法:
重新配置和编译NS-3,配置行用 --with-pybindgen加上pybindgen所在目录:

  • sudo ./waf -d debug --enable-examples --enable-tests configure --with-pybindgen=~/NS3/ns-allinone-3.29/pybindgen-0.17.0.post49+ng0e4e3bc/
  • sudo ./waf
2.NetAnim

(我在安装这个软件的时候情况比较复杂,我就以我的例子进行讲解)
NetAnim工具使用参考网址:http://www.nsnam.org/wiki/index.php/NetAnim

1.安装依赖包并下载

当你已经完全按照上述的步骤进行完并确保正确以后,在ns3的目录下会有一个netanim-3.108文件夹


示例

但网上的部分教程会让你进入这个文件夹下再继续操作命令,可是当我进入这个文件夹下操作命令的时候就会出现错误,错误如下:


示例2

这种时候有可能是因为你没有安装依赖包(最好在根目录下安装比较好)则输入以下命令来安装依赖包:
  • sudo apt-get install mercurial
    安装mercurial


    步骤1
  • sudo apt-get install qt4-dev-tools
    NetAnim是基于Qt4图形库的,所以要先安装Qt4。Ubuntu系统安装Qt4


    步骤2
  • sudo make clean
    执行这个命令时,网上的部分教程会让你进入到netanim-3.108文件夹下执行,但是我的就出现了问题,问题如下:


    问题1

    这个时候不要慌(虽然我是慌了一个晚上)
    这个问题为什么会产生我其实还是不太懂,但是对于这个问题的解决,我认为有两种办法,
    你可以重新安装上面两个插件或者不进入netanim-3.108这个目录,直接在usr/ns3/ns-3.29/这个目录下执行sudo make clean,我就说在这个目录下执行成功的,成功界面如下:


    成功提示

    然后在执行下面的命令:
  • sudo qmake NetAnim.pro
    在输入这个命令的时候,系统也给我报错了,于是我又安装了一个系统提示的插件


    步骤3

    也许你们直接就执行成功就不需要安装这个插件了
    (插件命令 : sudo apt install qtchooser)
    执行成功的界面:


    成功界面

    然后继续执行下面命令:
  • sudo make


    步骤4

    这个时候NetAnirm以及安装好了,检查它是否安装完成:

  • cd /usr/ns3/ns-3.29/netanim-3.108/
    进入到这个目录下查找一个名字叫NetAnirm的绿色字体的文件,如果有恭喜你这个软件安装成功了。


    示例1

    示例2

    以上你安装完了NetAnirm软件,那么下面使用它。

2.使用方法
  • 生成XML文件
  • 在NetAnim软件中打开XML文件
    1.在/usr/ns3/ns-3.29/scratch/目录下
  • cd /usr/ns3/ns-3.29/scratch/
    2.编辑myfirst.cc文件
  • sudo vi myfirst.cc
    按i进行编辑文件
    首先在myfirst.cc里面,加上头文件:
#include "ns3/netanim-module.h"

run前面加上三句代码:

AnimationInterface anim("myfirst.xml");
anim.SetConstantPosition(nodes.Get(0), 1.0, 2.0);
anim.SetConstantPosition(nodes.Get(1), 2.0, 3.0);

Simulator::Run();
Simulator::Destroy();
return 0

按Esc保存,wq!退出
第二三行是描绘两个节点的坐标,也可以不要这两行
这样再运行一下myfirst.cc文件:

  • cd ..
  • sudo ./waf


    步骤1
  • sudo ./waf --run scratch/myfirst


    步骤2
  • ls
    查看此目录文件下是否生成一个名字为myfirst.xml的文件,如果有那么生成xml文件成功。


    步骤3
  • cd /usr/ns3/netanim-3.108/
    进入到这个目录下,重新启动NetAnim软件


    步骤4
  • sudo ./NetAnim


    步骤5

    出现仿真界面:


    步骤1

    点击这个文件夹图案:
    步骤2

    找到刚刚生成的myfirst.xml文件并Open:


    步骤3

    出现这个界面,那么就说明你已经成功了!
    界面

    (此文章仅作为个人学习笔记使用,如有错误欢迎指正~)

你可能感兴趣的:(用NS3进行虚拟仿真)