一、 NS3仿真环境安装
内容参考:https://blog.csdn.net/m0_53498801/article/details/131731054
安装环境:ubuntu 22.04.1、ns 3.39
1.在命令行中输入:(需要几分钟克隆)
1| git clone https://gitlab.com/nsnam/ns-3-dev.git
2| cd ns-3-dev
2.使用 CMake 生成系统配置,构建 ns-3 模块库和可执行文件:(第二个指令需要几分钟)
./ns3 configure --enable-examples --enable-tests
./ns3 build
若成功则显示为
3.运行测试文件检验是否生成:
./test.py
若全通过或跳过,则成功配置好ns3环境,ns-3模拟器可以开始运行程序了。
二、脚本文件以及网络构建
该部分先介绍脚本编写的一般步骤,后根据first.cc文件具体分析。
1.网络核心概念
节点
ns-3中的节点代表网络中的基本计算设备(或者叫计算机)。当然节点仅仅是个计算机,要想使它工作,还需要添加网卡,协议栈,应用程序。节点用Node类表示,下面两行代码会创建两个节点对象,它们在仿真中代表计算机。
NodeContainer nodes;
nodes.Create(2);
应用
ns-3中的应用表示需要被仿真的用户程序。在C++中用Application类描述。有以下几种:
bulk-send-application
on-off-application
udp-client/server
udp-echo-client/server
信道
与其他条件下的信道概念类似,ns-3中,节点需要连接到信道上来进行数据交换,在C++中用Channel类来描述,一个信道实例可以模拟一条简单的线缆,也可以是一个复杂的巨型以太网交换机,甚至是一个无线网络中充满障碍物的三维空间。有以下几种:
CsmaChannel
PointToPointChannel
Wi-FiChannel
网络设备
ns-3中的网络设备相当硬件设备和软件驱动的总和。网络设备安装在节点上,然后节点之间通过信道和其他节点通信。这个网络和信道是相对应的,就像无线网卡不能连接网线,只能在在无线环境中使用。C++中用NetDevice类来描述网络设备。
2.网络搭建步骤
步骤 | 实例 |
---|---|
创建节点 | NodeContainer |
创建链路类型 | XxxDeviceHelper |
安装链路类型;生成网卡 | XxxDeviceContainer=XxxDeviceHelper.install(NodeContainer) |
安装协议栈 | XxxStack.install(NodeContainer) |
配置IP地址 | XxxAddressHelper.setBase(“IP”,“NETMASK”) |
生成网络接口 | XxxInterfaceContainer = XxxAddressHelper.Assign(NetDeviceContainer ) |
安装应用 | ApplicationContainer = XxxHelper.Install(NodeContainer); |
开始仿真 |
3.结合first.cc具体分析
内容参考:https://blog.csdn.net/qq_41816035/article/details/86648514
/* -*- 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"
//使用ns3命名空间
using namespace ns3;
//日志组件
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
//主函数
int
main (int argc, char *argv[])
{
//开启命令行传参数
CommandLine cmd;
cmd.Parse (argc, argv);
//使两个日志组件生效,两个组件被内建在Echo Client和Echo Server的应用中,日志级别为INFO。当
仿真产生数据分组发送和接收时,对应的应用就会输出相应的日志消息到相关的日志模块。通过程序的输
出了解程序执行的细节。
Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
//生成网络节点,NodeContainer类是ns3的一个helper类,能一次操作多个节点,并把指向这2个对象的
指针存储在系统之中。如果一个设备Helper类想安装设备到大量相似的节点,就可以使用NodeContainer
类型的变量做参数。此处相当于生成两个计算机空壳。
NodeContainer nodes;
nodes.Create (2);
//实际中物理连接两台计算机成为网络一般来说需要网卡和网线,ns3中将对应的物理实体抽象为网络设
和信道两个概念,下面的语句就实现了网络节点物理连接。Helper类是一族类,几乎所有的模块都有相应
的一个或若干个Helper类,负责把网络设备连接到节点、信道,配置IP地址等普遍任务。
PointToPointHelper类负责设置网络设备和信道属性,并通过Install方法把设备安装到节点中。信道和
网络设备是对应的。第一行初始化了一个对象pointToPoint,而接下来的一行从上层的角度告诉
PointToPointHelper对象当创建一个PointToPointNetDevice对象时使用“5Mbit/s”来作为数据速率。
从细节方面将,字符串“DataRate:与PointToPointNetDevice的一个属性相对应。与它类似,
PointToPointChannel也有一个Delay属性告诉PointToPointHelper使用“2ms”作为每一个被创建的点到
点信道的传输延时值。
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
//正如使用NodeContainer拓扑助手对象来模拟创建节点,我们会让PointToPointHelper来做关于创
建、配置和安装设备的工作。需要一个保存所有被创建的NetDevice对象列表,所以使用一个
NetDeviceContainer对象来存放它们,就像使用一个NodeContainer对象来存放自身所创建节点。现在
有一个包含两个节点NodeContainer对象,有一个准备在2个节点之间创建PointToPointNetDevice和
wirePointToPointChannel对象的PointToPointHelper对象。下面两行代码会完成设备和信道的配置。
第一行声明了上面提到的设备容器,第二行完成了主要工作。PointToPointHelper的Install()方法以
一个Node Container对象最为参数,在Install()方法内,一个NetDevice Container被创建了。当调
用了pointToPoint.Install(nodes)后,会有2个节点,每一个节点安装了点到点网络设备,在它们之
间是一个点到点信道。2个设备会被配置在一个有2ms传输延时的信道上以5Mbit/s的速率传输数据。
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
//为计算机安装协议栈,InternetStackHelper会为每一个节点容器中的节点安装一个网络协议栈,主要是IP层。
InternetStackHelper stack;
stack.Install (nodes);
//Ipv4AddressHelper为一个地址助手对象,告诉它应该从10.1.1.0开始以子网掩码为255.255.255.0分
配地址,地址分配默认是从1开始并单调增长,为节点上的设备设置IP地址。
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
//这行完成了真正的地址配置。在ns3中使用Ipv4Interface对象将一个IP地址同一个设备关联起来。需
要一个Ipv4InterfaceContainer保存对象列表。现在有了一个安装了协议栈,配置了IP地址类的点到点
的网络。这时所要做的事情时运用它来产生数据通信。
Ipv4InterfaceContainer interfaces = address.Assign (devices);
//下面的代码用来安装服务器端应用程序、设置端口号,这个并非应用本身,是一个用来帮助创建真正应
用的对象。除非我们告诉这个助手服务器和客户端所共知的一个端口号,否则这个助手是不会起任何作
用。
UdpEchoServerHelper echoServer (9);
//UdpEchoServerHelper对象有一个Install方法,实际上是这个方法的执行,才初始化回显服务器的应
用,并将应用连接到一个节点上去。安装方法把NodeContainer当作一个参数,这里有一个C++隐式转换,
此转换以nodes.Get(1)的结果作为参数,最终这个未命名的NOdeContainer被送到Install方法中。
echoServer.Install将会在管理节点的NodeContainer容器索引号为1的机节点上安装一个
UdpEchoServerApplication。安装会返回一个容器,这个容器中包含了指向所有被助手创建的应用指
针。应用对象需要一个时间参数来开始产生数据通信并且可能在一个可选的时间点停止。这两个方法以
Time对象为参数,使用了一种明确的C++转换序列来获得C++双精度的1.0,并且用一个Seconds转换来把
它转换到ns3的Time对象。下面几行会使echo服务应用在1s时开始(生效)并在10s时停止(失效)。
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
//设置客户端应用层,客户端应用的设置与服务器端类似。也有一个UdpEchoClientHelper来管理
UdpEchoClientApplication。然而,对于echi客户端,需要设置5个不同的属性。首先2个属性是在
UdpEchoClientHelper的创建过程中被设置的。按照助手构造函数的格式,把RemoteAddress和
RemotePort属性传递给了助手(实际上是作为助手构造函数的2个必须参数传递的)。在界面容器中位置
0的界面对象将会和节点容器中位置0的节点对象对应.下面第一行告诉它设置客户端的远端地址为服务器节
点的IP地址。同样告诉它准备发送第二个数据分组到端口9 。MaxPackets属性告诉客户端所允许它在模拟
期间能发送的最大数据分组个数。Inteval属性告诉客户端2个数据分组之间要等待多长时间。而
PacketSize属性告诉客户端它的数据分组应该承载多少数据。
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
//和服务端类似,客户端在服务端生效1s后才开始。
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
//启动模拟器,这是用全局变量来运行模拟器。当Simulator::Run被调用时,系统会开始遍历预设事件
列表并执行。当执行完剩下的事情就是清理,销毁所有被创建的事件。
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
mian函数的逻辑
//1.创建节点
NodeContainer nodes;
nodes.Create(2);
//2.定义网卡网线(网络设备和信道),
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
//3.完成设备和信道的配置,将网络设备和信道装载到节点上
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
//4. 安装协议栈
InternetStackHelper stack;
stack.Install (nodes);
//5.设置IP地址
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
//6.配置IP地址
Ipv4InterfaceContainer interfaces = address.Assign (devices)
//7.监听9号端口
UdpEchoServerHelper echoServer (9);
//8.定义服务器端连接属性。使用install方法将Application安装在节点上。Application在第1s开始运行并接受9号端口的数据,并在10s停止
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
//9.配置客户端属性
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); //客户端助手类UdpEchoClientHelper在节点0创建一个客户端应用echoClient
echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); //允许发送的最大数据分组个数
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); //2个数据分组之间需要间隔的时间
echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); // 数据分组的大小(承载多少数据)
//10.定义客户端连接属性,在模拟启动后2s向节点1的9号端口发送一个1024bit的UDP数据包,在模拟启动后10停止。
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
//11.启动与结束
Simulator::Run ();
Simulator::Destroy ();
return 0;
4、运行第一个示例
在ns-3-dev/examples/tutorial文件夹下找到了第一个示例first.cc,并将文件复制到ns-3-dev/scratch中,在ns-3-dev目录下运行,输入下面指令:
./ns3 run first
运行结果如下图: