EngineeringClinic-网络模拟器-3-教程笔记-全-
EngineeringClinic 网络模拟器 3 教程笔记(全)
01:解析second.cc与ASCII追踪及NetAnim
在本节课中,我们将学习NS3网络模拟器中的second.cc示例文件。我们将探讨其如何结合点对点网络和CSMA网络进行工作,并学习如何使用ASCII追踪文件和NetAnim工具来可视化和分析模拟结果。

概述

second.cc示例构建了一个包含点对点链路和CSMA总线网络的混合拓扑。一个节点通过点对点链路连接到CSMA网络,并向网络中的服务器节点发送数据包。我们将通过修改代码参数、运行模拟、分析数据包捕获文件以及使用网络动画来深入理解其工作原理。
代码结构与解析


上一节我们概述了示例的目标,本节中我们来看看second.cc脚本的具体代码结构及其关键组成部分。
首先,脚本定义了网络拓扑:包含两个点对点节点和多个CSMA节点。核心变量nCsma定义了额外的CSMA节点数量,默认为3。
uint32_t nCsma = 3;
命令行参数可以修改此值。verbose布尔变量用于控制是否输出应用程序的日志信息。
bool verbose = true;
以下是节点创建与拓扑构建的主要步骤:
-
创建节点容器:分别为点对点链路和CSMA网络创建节点容器。
NodeContainer p2pNodes; p2pNodes.Create(2); NodeContainer csmaNodes; csmaNodes.Add(p2pNodes.Get(1)); csmaNodes.Create(nCsma);注意,
p2pNodes.Get(1)同时被添加到了csmaNodes容器中,作为连接两个网络的桥梁。 -
安装网络设备与信道:使用
PointToPointHelper和CsmaHelper为节点安装网络设备并设置信道属性(如带宽、延迟)。PointToPointHelper pointToPoint; pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); NetDeviceContainer p2pDevices = pointToPoint.Install(p2pNodes); CsmaHelper csma; csma.SetChannelAttribute("DataRate", StringValue("100Mbps")); csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560))); NetDeviceContainer csmaDevices = csma.Install(csmaNodes); -
安装协议栈与分配IP地址:为所有节点安装互联网协议栈,并为两个子网分配IP地址。
InternetStackHelper stack; stack.Install(p2pNodes.Get(0)); stack.Install(csmaNodes); Ipv4AddressHelper address; address.SetBase("172.16.1.0", "255.255.255.0"); Ipv4InterfaceContainer p2pInterfaces = address.Assign(p2pDevices); address.SetBase("172.16.2.0", "255.255.255.0"); Ipv4InterfaceContainer csmaInterfaces = address.Assign(csmaDevices); -
设置应用层通信:配置一个UDP回声服务器和客户端。服务器位于CSMA网络中的最后一个节点,客户端位于点对点网络的第一个节点。
UdpEchoServerHelper echoServer(1234); ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma)); serverApps.Start(Seconds(1.0)); serverApps.Stop(Seconds(10.0)); UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 1234); echoClient.SetAttribute("MaxPackets", UintegerValue(3)); echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0))); echoClient.SetAttribute("PacketSize", UintegerValue(2048)); ApplicationContainer clientApps = echoClient.Install(p2pNodes.Get(0)); clientApps.Start(Seconds(2.0)); clientApps.Stop(Seconds(10.0)); -
启用数据包捕获:启用指定链路的PCAP文件记录,便于后续使用Wireshark等工具分析。
pointToPoint.EnablePcapAll("second"); csma.EnablePcap("second", csmaDevices.Get(1), true); csma.EnablePcap("second", csmaDevices.Get(3), true); -
运行模拟:启动模拟器。
Simulator::Run(); Simulator::Destroy();


运行模拟与基础分析


理解了代码结构后,本节中我们来看看如何编译、运行这个脚本并观察其基本输出。
使用以下命令在scratch目录下编译并运行脚本:
./waf --run scratch/second
模拟运行时,控制台会输出数据包发送和接收的日志(如果verbose为真)。通过修改代码中的参数,如IP地址、数据包数量、大小、发送间隔等,初学者可以直观地观察网络行为的变化。
模拟结束后,会在当前目录生成.pcap数据包捕获文件。可以使用Wireshark或tcpdump命令打开并分析这些文件,查看协议头细节、数据流向等信息。
使用NetAnim进行可视化
除了分析数据包,我们还可以直观地观察网络动态。本节介绍如何使用NetAnim工具为模拟添加动画效果。
首先,需要在second.cc文件开头包含NetAnim头文件,并在main函数中添加动画设置代码:
#include "ns3/netanim-module.h"
...
AnimationInterface anim("second.xml");
anim.SetConstantPosition(p2pNodes.Get(0), 10.0, 10.0);
anim.SetConstantPosition(csmaNodes.Get(0), 20.0, 20.0);
anim.SetConstantPosition(csmaNodes.Get(1), 30.0, 30.0);
anim.SetConstantPosition(csmaNodes.Get(2), 40.0, 40.0);
anim.SetConstantPosition(csmaNodes.Get(3), 50.0, 50.0);
重新编译并运行脚本后,会生成second.xml文件。使用NetAnim工具打开此文件:
./netanim-3.108/NetAnim second.xml

在NetAnim界面中,可以播放模拟动画,观察数据包从客户端节点发出,经点对点链路到达网关节点,再通过CSMA总线广播,最终被服务器节点接收并回复的全过程。界面中的统计信息还可以展示节点间数据包交换的详细记录。

使用ASCII追踪与TraceMetrics分析
为了进行定量分析,例如计算吞吐量,我们可以启用ASCII格式的追踪。本节介绍如何配置并使用TraceMetrics工具。
在second.cc的main函数中,在启用PCAP的代码附近,添加ASCII追踪的代码:
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll(ascii.CreateFileStream("p2p.tr"));
csma.EnableAsciiAll(ascii.CreateFileStream("csma.tr"));

重新运行模拟后,会生成p2p.tr和csma.tr两个ASCII追踪文件。我们可以使用NS3自带的traceMetrics工具(一个Java JAR程序)来分析这些文件,特别是CSMA网络的性能。
运行以下命令启动分析工具:
java -jar traceMetrics.jar
在工具界面中加载csma.tr文件,选择要分析的节点(例如作为网关和服务器的那两个活跃节点),执行分析。工具会提供吞吐量、延迟等指标的统计结果,帮助我们理解网络在负载下的表现。

总结

本节课中我们一起学习了NS3的second.cc示例。我们从分析其混合网络拓扑的代码开始,学习了如何设置点对点和CSMA网络、配置UDP应用、启用数据包捕获。接着,我们运行了模拟,并使用Wireshark分析网络流量。然后,我们通过集成NetAnim模块,实现了模拟过程的可视化动画。最后,我们启用了ASCII追踪,并利用TraceMetrics工具对网络性能进行了定量分析。这个示例综合运用了NS3的多种功能,是深入学习网络协议和模拟分析的良好起点。
02:详解first.cc与ASCII追踪及NetAnim 🖥️
在本节课中,我们将学习NS3网络模拟器的入门知识,重点分析一个名为first.cc的示例程序。我们将了解其源代码结构,并学习如何集成ASCII追踪和NetAnim网络动画工具来可视化模拟过程。
概述
对于任何网络模拟器的初学者,首要问题通常是“从哪里开始”以及“如何开始”。NS3提供了丰富的示例代码,其中first.cc是一个演示点对点网络通信的经典入门程序。本节我们将逐行解析此代码,并演示如何为其添加网络动画和包追踪功能,以便更直观地理解模拟过程。
源代码结构与解析
上一节我们介绍了NS3的基本概念和安装。本节中,我们来看看first.cc这个基础示例的代码结构。
首先,程序包含了必要的头文件:
#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[]) {
Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);


创建网络节点与设备

以下是创建两个网络节点并配置点对点连接的步骤:
-
创建节点:使用
NodeContainer创建两个网络节点。NodeContainer nodes; nodes.Create (2); -
配置点对点链路:使用
PointToPointHelper设置链路的数据速率和延迟。PointToPointHelper pointToPoint; pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); -
安装网络设备:将点对点设备安装到节点上,形成
NetDeviceContainer。NetDeviceContainer devices; devices = pointToPoint.Install (nodes);
配置网络协议栈与IP地址
节点创建完成后,需要为其安装网络协议栈并分配IP地址。
-
安装协议栈:使用
InternetStackHelper为所有节点安装TCP/IP协议栈。InternetStackHelper stack; stack.Install (nodes); -
分配IP地址:使用
Ipv4AddressHelper为点对点设备分配IP地址。Ipv4AddressHelper address; address.SetBase ("10.1.1.0", "255.255.255.0"); Ipv4InterfaceContainer interfaces = address.Assign (devices);
创建服务器与客户端应用
网络基础设施搭建好后,我们需要在上面运行应用程序。以下是创建UDP回声服务器和客户端的步骤:

- 创建UDP回声服务器:在第二个节点(索引1)上监听端口9。
UdpEchoServerHelper echoServer (9); ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0));

- 创建UDP回声客户端:在第一个节点(索引0)上配置,使其向服务器的IP地址和端口发送数据包。
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;
编译并运行此程序,将在终端看到类似如下的输出,显示客户端与服务器之间数据包的发送与接收:
At time 2s client sent 1024 bytes to 10.1.1.2 port 9
At time 2.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 2.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 2.00737s client received 1024 bytes from 10.1.1.2 port 9

集成NetAnim网络动画
为了更直观地观察数据包的流动,我们可以为first.cc添加NetAnim支持。

首先,在源代码中包含NetAnim模块的头文件:
#include "ns3/netanim-module.h"
然后,在Simulator::Run()语句之前,添加以下代码来创建动画接口并设置节点位置:

AnimationInterface anim ("first.xml");
anim.SetConstantPosition (nodes.Get (0), 10.0, 10.0);
anim.SetConstantPosition (nodes.Get (1), 20.0, 20.0);
重新编译并运行程序后,会生成一个first.xml文件。使用NS3自带的NetAnim工具打开此文件:

cd netanim-3.108
./netanim
在NetAnim界面中打开first.xml文件,即可播放模拟动画,看到数据包在两个节点间传输的可视化效果。
启用ASCII追踪

除了图形化动画,我们还可以生成ASCII格式的包追踪文件,用于详细分析每个数据包。

在Simulator::Run()语句之前,添加以下代码启用ASCII追踪:
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("first.tr"));


重新运行程序后,会生成一个first.tr文件。该文件以文本形式详细记录了模拟过程中每个数据包在队列中的进入、离开、丢弃等事件。
使用TraceMatrix分析追踪文件

first.tr文件可以被TraceMatrix工具进一步分析。TraceMatrix是一个基于Java的图形化分析工具。



- 确保系统已安装Java。
- 下载并解压TraceMatrix软件包。
- 在TraceMatrix目录下,运行以下命令启动工具:
java -jar trace-compass.jar - 在TraceMatrix界面中,打开生成的
first.tr文件。
工具将提供模拟的统计摘要,包括总包数、发送/接收包数、吞吐量、端到端延迟等信息,并以图表形式展示节点间的数据流。
总结


本节课我们一起学习了NS3入门程序first.cc的完整代码结构。我们从创建节点、配置链路、分配IP地址,到部署UDP回声应用,逐步构建了一个简单的点对点网络模拟。此外,我们还学习了如何集成NetAnim来可视化模拟过程,以及如何使用ASCII追踪和TraceMatrix工具来记录和分析数据包的详细传输情况。掌握这个基础示例是理解更复杂NS3模拟的关键第一步。
03:Ubuntu系统逐步安装指南 🖥️
在本节课中,我们将学习如何在Ubuntu 16.04操作系统上逐步安装网络模拟器3(NS3)。本教程将指导您完成从系统更新到编译运行第一个示例的全部过程。


概述与准备工作
首先,请确保您使用的是Ubuntu 16.04操作系统。本教程录制于2018年3月,但安装步骤对于后续版本同样具有参考价值。我们将使用两个窗口进行操作:一个用于记录命令的文本编辑器,另一个用于执行安装命令的终端。


第一步:更新系统包列表
安装任何软件前,更新系统包列表是一个好习惯。这能确保我们获取到最新的软件源信息。

以下是更新命令:
sudo apt update
执行此命令后,系统会检查可用的更新。如果所有包都已是最新,则会显示相应提示。
第二步:升级已安装的包


接下来,我们可以选择升级系统中已安装的包到最新版本。
升级命令如下:
sudo apt upgrade
如果您的系统近期已更新过,此步骤可能会很快完成,并提示无需升级。

第三步:安装NS3所需的依赖库

NS3的运行和编译依赖于大量的开发库。在安装NS3本身之前,必须先安装这些依赖项,以避免后续出现错误或警告。
以下是需要安装的依赖包长命令:
sudo apt install gcc g++ python python-dev mercurial bzr gdb valgrind gsl-bin libgsl0-dev libgsl0ldbl flex bison tcpdump sqlite sqlite3 libsqlite3-dev libxml2 libxml2-dev libgtk2.0-0 libgtk2.0-dev vtun lxc uncrustify doxygen graphviz imagemagick texlive texlive-extra-utils texlive-latex-extra texlive-font-utils texlive-lang-portuguese texlive-latex-recommended python-sphinx dia python-pygraphviz python-kiwi python-pygoocanvas libgoocanvas-dev python-pygccxml
这个命令将安装包括C/C++编译器、Python开发环境、构建工具(如CMake、Mercurial)、图形库(如GTK、QT4)以及各种Python库在内的大量软件包,总计约223MB。安装过程中,如果遇到关于Wireshark权限的警告,选择允许普通用户运行即可。

第四步:下载并解压NS3源码
假设您已将NS3的源码压缩包(例如 ns-allinone-3.27.tar.bz2)下载到主目录(~/)。您可以从官方网站 nsnam.org 获取。
首先,进入您的主目录:
cd $HOME
然后,使用 tar 命令解压源码包。-j 选项用于处理bz2压缩,-x 表示解压,-v 显示详细过程,-f 指定文件名。


解压命令如下:
tar -jxvf ns-allinone-3.27.tar.bz2
解压完成后,当前目录下会生成一个名为 ns-allinone-3.27 的文件夹。
第五步:编译构建NS3
解压后,需要进入该目录并开始编译构建NS3库。NS3支持使用C++或Python进行开发,您可以根据熟悉程度选择。



进入解压后的目录:
cd ns-allinone-3.27/ns-3.27
使用提供的Python构建脚本进行配置和编译。--enable-examples 和 --enable-tests 选项可以一并编译示例和测试程序。

构建命令如下:
./build.py --enable-examples --enable-tests
执行此命令将开始编译NS3的所有模块。这是一个耗时过程,在普通机器上可能需要15到30分钟,在虚拟机上可能更久。请耐心等待。屏幕上会显示正在构建的包(总共约70个)。



第六步:验证安装与运行示例

编译成功后,会列出所有已构建和未构建的模块(如openflow可能需要单独安装)。接下来,我们通过运行示例程序来验证安装是否成功。

NS3的应用程序需要放在 scratch 目录下才能被执行。首先,我们运行一个内置的简单测试:


./waf --run hello-simulator
如果输出“Hello Simulator”,则说明框架基本正常。

为了运行更复杂的示例,我们需要将示例文件复制到 scratch 目录。例如,复制第一个教程文件:
cp examples/tutorial/first.cc scratch/
cp examples/tutorial/first.py scratch/
现在,可以运行C++版本的示例了。注意,运行C++程序时不需要指定文件扩展名。
运行C++示例命令:
./waf --run scratch/first
运行成功后,终端会显示两个节点(node0和node1)之间交换数据包的模拟输出。

接下来,运行Python版本的同一示例。注意,运行Python程序时必须指定 .py 扩展名。



运行Python示例命令:
./waf --pyrun scratch/first.py
如果命令格式错误(例如为C++程序加了扩展名,或为Python程序省略了扩展名),NS3会给出明确的错误提示,请根据提示修正命令。


总结

本节课中,我们一起完成了在Ubuntu系统上安装网络模拟器3(NS3)的全过程。我们首先更新并升级了系统,然后安装了所有必要的依赖库。接着,下载并解压了NS3源码,使用构建脚本完成了耗时但重要的编译步骤。最后,通过将示例文件移动到 scratch 目录并成功运行,验证了NS3安装的正确性。记住,NS3允许您使用C++或Python进行开发,这为不同背景的研究者提供了便利。
更多详细信息和更新,请参考官方网站和社区文档。
04:在NS3中安装与使用AquaSim-NG水下网络模拟器 🐠
概述
在本节课中,我们将学习如何在网络模拟器3(NS3)中安装AquaSim-NG,这是一个专门用于模拟水下传感器网络的扩展模块。我们将从安装步骤开始,逐步介绍如何配置、编译并运行一个简单的水下网络广播示例。
AquaSim-NG简介与背景
上一节我们介绍了NS3的基本安装,本节中我们来看看AquaSim-NG。AquaSim最初是为NS2开发的,主要用于水下传感器网络研究,支持二维和三维模型。由于操作系统更新,原版AquaSim在Ubuntu、Linux Mint等系统中兼容性不佳。近年来,AquaSim-NG作为新一代版本被开发出来,专为NS3设计,支持多种介质访问控制协议和基于向量的转发算法。


安装前提条件
在安装AquaSim-NG之前,必须确保NS3已经正确安装在系统中。本教程基于NS3版本3.27,在Ubuntu 16.04或Linux Mint 18.1系统中测试通过。虽然最新版NS3 3.28尚未官方测试,但通常也能正常工作。
安装步骤
以下是安装AquaSim-NG的具体步骤:
1. 进入NS3源代码目录
首先,打开终端并进入NS3的源代码目录。假设NS3安装在用户主目录下:
cd ~/ns-3.27/ns-3.27/src
2. 克隆AquaSim-NG仓库
使用Git克隆AquaSim-NG的源代码仓库。必须确保文件夹名称为aqua-sim-ng,否则可能导致编译错误:
git clone https://github.com/martinif/aqua-sim-ng.git
3. 配置与编译
返回NS3主目录并运行配置脚本。如果遇到Python绑定错误,可以添加--disable-python选项:
cd ~/ns-3.27/ns-3.27
./waf --enable-examples --enable-tests configure
如果出现错误,尝试以下命令:
./waf --disable-python --enable-examples --enable-tests configure
4. 编译模块
运行编译命令。如果NS3已预先安装,此过程将较快完成:
./waf
编译成功后,终端会显示aqua-sim-ng模块已成功构建。


运行示例程序
AquaSim-NG提供了多个示例程序。以下是如何运行一个简单的广播MAC层示例:
1. 复制示例文件
进入AquaSim-NG的示例目录,将广播示例复制到NS3的scratch文件夹:
cd ~/ns-3.27/ns-3.27/src/aqua-sim-ng/examples
cp broadcast-mac-example.cc ../../scratch/

2. 运行示例
返回NS3主目录并运行示例程序:
cd ~/ns-3.27/ns-3.27
./waf --run scratch/broadcast-mac-example
程序运行后,终端会显示节点创建、位置初始化及广播过程。这是一个基础的水下网络广播示例,展示了节点如何在水下环境中通过广播建立网络连接。
总结
本节课中我们一起学习了如何在NS3中安装和配置AquaSim-NG水下网络模拟器。我们从背景介绍开始,逐步完成了环境准备、源代码克隆、模块编译和示例运行。AquaSim-NG为水下传感器网络研究提供了强大的三维模拟支持,适用于各种介质访问控制和路由协议测试。
通过本教程,你应该能够成功安装AquaSim-NG并运行基础示例。后续课程中,我们将深入探讨更复杂的水下网络模拟场景和性能分析方法。
05:使用Gnuplot绘制数据 📊
在本节课中,我们将学习一个名为Gnuplot的强大工具。Gnuplot是一个用于绘制二维和三维图形的工具,它可以通过简单的代码生成高质量的图表。研究人员和学生在发表论文时,图表的专业性是重要的评判标准之一。虽然我们常用Microsoft Excel等电子表格软件绘图,但Gnuplot作为一个已有三十多年历史的工具,在全球范围内提供了强大的绘图解决方案。
安装Gnuplot 🛠️
首先,我们需要安装Gnuplot。在基于Debian的系统(如Ubuntu)上,安装过程非常简单。
以下是安装命令:
sudo apt install gnuplot
安装完成后,您可以在终端输入gnuplot命令来启动它。如果已经安装,系统会显示Gnuplot的终端界面,等待您输入命令。


Gnuplot基础功能


Gnuplot不仅能处理数据文件,还能直接绘制数学函数。例如,在Gnuplot终端中输入以下命令可以绘制正弦函数:
plot sin(x)
这里,x是Gnuplot默认识别的变量。同样,您可以绘制余弦函数cos(x)或线性方程4*x + 10。

准备数据文件与脚本文件 📁

为了演示如何使用数据文件绘图,我们需要创建两个文件:一个数据文件和一个Gnuplot脚本文件。
-
数据文件 (
my_data.txt):此文件包含我们要绘制的数据。我们创建一个包含四列数据的示例文件:- 第一列:可以代表时间或序号(例如:1, 2, 3, ...)。
- 第二列:代表车辆速度(单位:公里/小时)。
- 第三列:代表驾驶员年龄。
- 第四列:代表驾驶员薪水。
文件内容示例如下:
1 34.5 45 2000 2 38.7 34 24000 3 32.3 22 34000 4 41.5 18 43000 5 35.6 24 2304 6 24.5 26 562345 7 56.7 67 670987 8 62.3 54 45678 9 65.4 27 3200123 10 70.1 33 89989 -
脚本文件 (
my_gnu_code.plt):这个文件包含一系列Gnuplot命令,用于控制图形的生成方式。
编写第一个绘图脚本 ✍️
现在,让我们编写一个基本的Gnuplot脚本来绘制数据。
在my_gnu_code.plt文件中输入以下内容:
# 设置输出为PDF格式
set terminal pdf
# 设置输出文件名
set output "pred.pdf"
# 设置图表标题
set title "Driver‘s Data"
# 设置X轴标签
set xlabel "Number of Days"
# 设置Y轴标签
set ylabel "Driver‘s Information"
# 绘制数据:使用数据文件的第一列作为X轴,第二列作为Y轴,用线条连接
plot "my_data.txt" using 1:2 with lines title "Speed in kmph"




保存文件后,在终端运行以下命令来生成图表:
gnuplot my_gnu_code.plt
命令执行成功后,会在当前目录生成一个名为pred.pdf的PDF文件,其中包含了根据第一列和第二列数据绘制的折线图。

在同一图表中添加多条曲线 📈




上一节我们绘制了单条曲线,本节中我们来看看如何在同一张图中叠加多条曲线,以便进行对比。



修改my_gnu_code.plt文件,在plot命令后添加更多数据系列,用逗号分隔:
set terminal pdf
set output "pred.pdf"
set title "Driver‘s Data"
set xlabel "Number of Days"
set ylabel "Driver‘s Information"
# 绘制多条曲线:速度(线条)和年龄(带点的线条)
plot "my_data.txt" using 1:2 with lines lw 2 title "Speed in kmph", \
"my_data.txt" using 1:3 with linespoints title "Age"
using 1:3表示使用第一列作为X轴,第三列作为Y轴。with linespoints表示图形同时包含线条和数据点。lw 2是linewidth 2的缩写,用于增加第一条曲线的线条粗细。



再次运行gnuplot my_gnucode.plt命令,生成的PDF中将同时显示速度和年龄两条曲线。


探索不同的绘图样式 🎨

Gnuplot支持多种绘图样式。以下是几种常见的样式示例,您可以替换with后面的关键词来尝试:

with impulses:绘制脉冲图(垂直线)。plot "my_data.txt" using 1:2 with impulses title "Speed"with points:仅绘制数据点,不连接线条。plot "my_data.txt" using 1:3 with points title "Age"

生成PNG格式图像并添加参考线 🖼️


有时我们需要生成图像文件(如PNG)用于网页或演示文稿。此外,在图表中添加参考线(如平均线、最低标准线)可以更清晰地传达信息。


以下脚本将生成一个PNG图像,并在图表中添加一条代表最低薪水的水平参考线:
# 设置输出为PNG格式,并指定图像尺寸为600x400像素
set terminal png size 600,400
# 设置输出文件名
set output "salary.png"
# 设置图表标题和坐标轴标签
set title "Driver‘s Data"
set xlabel "Number of Drivers"
set ylabel "Driver‘s Salary"
# 绘制数据:薪水曲线,并添加一条Y=20000的水平参考线
plot "my_data.txt" using 1:4 with linespoints lw 2 title "Salary in rupees", \
20000 title "Minimum Salary"
运行此脚本后,将生成salary.png文件。图中的水平线直观地标出了20000的最低薪水标准,我们可以快速看出有哪些数据点位于此标准之下。



总结 📝


本节课中我们一起学习了Gnuplot的基础使用方法。我们了解了如何安装Gnuplot,如何准备数据文件和编写绘图脚本,以及如何生成包含多条曲线、不同样式和参考线的PDF与PNG格式图表。Gnuplot功能强大且灵活,是进行科研数据可视化的优秀工具。掌握这些基础后,您可以进一步探索其绘制直方图、三维曲面图等高级功能。
01:NS3 简介与安装

在本节课中,我们将学习网络模拟器3(NS3)的基本概念、它与NS2的主要区别,以及如何在Linux系统上完成NS3的安装与配置。
概述
NS3是一个开源的离散事件网络模拟器,主要用于研究和教育。与NS2不同,NS3主要基于C++语言,并提供了可选的Python绑定,使其在架构和易用性上更具优势。
NS3 与 NS2 的主要区别
上一节我们了解了NS3的基本定位,本节中我们来看看它与前代NS2的核心区别。
以下是NS3与NS2的关键差异点:
- 编程语言:NS2需要同时掌握Tcl和C++两种语言。而NS3主要使用C++,并可选Python进行开发。
- 架构与维护:NS2的架构较为陈旧,自2011年后基本停止重大更新。NS3采用模块化库设计,社区活跃,大约每三个月发布一次更新。
- 跟踪与分析:NS2生成专用的跟踪文件,需用特定工具分析。NS3生成标准的pcap(数据包捕获)文件,可使用Wireshark等通用行业工具进行分析。
- 功能特性:NS3支持直接代码执行,意味着在模拟器中编写的代码逻辑可以部署到真实硬件上运行,这是NS2不具备的功能。
- 可视化工具:NS2使用自带的NAM动画器。NS3支持多种外部工具,如NetAnim、PyViz等,并可与更多第三方数据分析和可视化工具集成。
NS3 的核心抽象概念
了解版本差异后,我们需要掌握NS3模拟中的五个基本抽象概念,它们是构建任何模拟场景的基石。
以下是NS3的五个核心抽象:
- 节点:代表网络设备,如计算机、路由器或交换机。
- 应用:运行在节点上的软件,用于生成或消费网络流量。
- 信道:节点之间进行通信的媒介,如电缆或无线链路。
- 网络设备:安装在节点上,使节点能够通过信道进行通信的硬件抽象,如网卡。
- 拓扑助手:用于简化复杂网络拓扑配置的辅助类。
NS3 安装指南
现在,我们开始进行NS3的安装。以下步骤基于Ubuntu系统,这是运行NS3的推荐环境。
步骤一:更新系统包
首先,打开终端并更新现有的软件包列表。
sudo apt-get update
步骤二:安装必备工具和依赖库
NS3的运行和编译需要一系列开发库和工具。以下是需要安装的软件包列表。
sudo apt-get install gcc g++ python python3 python3-dev pkg-config sqlite3 cmake build-essential autoconf automake libxml2-dev libgtk-3-dev libgtk2.0-dev vtun lxc wireshark python-pygccxml python-pygraphviz python-kiwi python-gnome2 ipython libc6-dev-i386
注意:libc6-dev-i386(32位库)在某些64位系统上可能不需要,如果安装失败可以忽略。
步骤三:下载并解压NS3
访问NS3官网下载稳定版本(例如ns-3.24.1)。将下载的压缩包保存到主目录,然后进行解压。
tar xjvf ns-allinone-3.24.1.tar.bz2
解压后,进入生成的目录。
cd ns-allinone-3.24.1
步骤四:构建NS3
使用waf构建系统来配置和编译NS3。建议启用示例和测试。
./waf configure --enable-examples --enable-tests
./waf build
这个过程可能需要10到30分钟。完成后,终端会显示哪些模块已成功构建。
步骤五:运行测试示例
构建完成后,可以运行一个简单的示例程序来验证安装是否成功。
./waf --run hello-simulator
如果终端输出“Hello Simulator”,则表明NS3已安装成功。
步骤六:运行更多示例
NS3自带大量示例程序,位于examples/目录下。要运行它们,需要将对应的.cc文件复制到scratch/目录,然后使用waf执行。
例如,运行一个名为first.cc的示例:
cp examples/tutorial/first.cc scratch/
./waf --run scratch/first
对于Python脚本,使用--pyrun参数:
./waf --pyrun scratch/my_script.py
总结

本节课中我们一起学习了网络模拟器3的基础知识。我们明确了NS3作为现代网络研究工具的优势,特别是其基于C++的简洁架构和对行业标准工具(如Wireshark)的良好支持。我们详细介绍了安装NS3所需的步骤,从系统准备、依赖安装到最终的构建与测试。现在,你已经拥有了一个可以运行的NS3环境,为后续深入学习网络协议模拟和性能分析打下了基础。
07:在Linux Mint中安装NS3 🖥️

在本教程中,我们将学习如何在64位的Linux Mint 17操作系统中安装网络模拟器NS3。NS3是一款使用C++和Python编程的软件,用于模拟或仿真特定的网络,例如有线网络、无线网络、4G/LTE网络、3G蜂窝网络等,适用于多种网络应用场景。
概述 📋
开始工作前,首先需要更新系统。如果这是您首次安装Linux,使用更新命令可以确保所有包管理器得到更新。根据您的网络带宽和速度,此过程可能需要一到两分钟。
更新完成后,需要安装一些基础软件包。以下是安装NS3所必需的核心包。
安装必备软件包 🔧
首先,我们需要安装包含完整配置、GCC编译器、X11图形界面编辑器以及开发工具的基础包。随后,安装NS3所需的特定软件包。
以下是需要安装的软件包列表:
- mercurial
- bzr
- gdb
- valgrind
- gsl-bin
- libgsl2
- libgsl-dev
- flex
- bison
- libfl-dev
- tcpdump
- sqlite
- sqlite3
- libsqlite3-dev
- libxml2
- libxml2-dev
- libgtk2.0-0
- libgtk2.0-dev
- vtun
- lxc
- libc6-dev
- libc6-dev-i386
- libcli-dev
- libssl-dev
- libssl0.9.8
- libssl1.0.0
- libsctp-dev
- libsctp1
- lksctp-tools
- git
- cmake
- libc6-dev-i386
- libstdc++6
- g++-multilib
- python-dev
- python-pygraphviz
- python-kiwi
- python-pygoocanvas
- python-gnome2
- python-rsvg
- python-setuptools
- autoconf
- automake
- libtool
- pkg-config
- libboost-all-dev
- libboost-filesystem-dev
- libboost-program-options-dev
- libboost-system-dev
- libboost-thread-dev
- libxmu-dev
- libxmu-headers
这些软件包总计下载量约为8MB,解压后约为40.3MB。使用以下命令进行安装:
sudo apt-get install mercurial bzr gdb valgrind gsl-bin libgsl2 libgsl-dev flex bison libfl-dev tcpdump sqlite sqlite3 libsqlite3-dev libxml2 libxml2-dev libgtk2.0-0 libgtk2.0-dev vtun lxc libc6-dev libc6-dev-i386 libcli-dev libssl-dev libssl0.9.8 libssl1.0.0 libsctp-dev libsctp1 lksctp-tools git cmake libc6-dev-i386 libstdc++6 g++-multilib python-dev python-pygraphviz python-kiwi python-pygoocanvas python-gnome2 python-rsvg python-setuptools autoconf automake libtool pkg-config libboost-all-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libxmu-dev libxmu-headers
下载并解压NS3 📦
所有必备软件安装完成后,现在可以安装NS3本身。我们将使用最新的稳定版本ns-3.21。
使用以下命令下载并解压NS3压缩包:
wget https://www.nsnam.org/release/ns-allinone-3.21.tar.bz2
tar -xjvf ns-allinone-3.21.tar.bz2
构建NS3 🛠️
解压完成后,进入解压后的目录并开始构建过程。构建过程会启用示例和测试。
cd ns-allinone-3.21
./build.py --enable-examples --enable-tests
此过程需要一些时间,系统会预先检查所有必需的软件。大约有224个主要软件包将被安装和配置。整个构建过程大约需要11分16秒,请耐心等待。
构建完成后,您可能会看到一些模块(如网络可视化器visualizer)未被构建,但核心的网络模块(如aodv、csma、dsdv、energy、internet、wifi、wimax、lte等)应该都已成功构建。
验证安装 ✅
为了验证NS3是否安装成功,我们可以运行一个简单的示例程序。
首先,清理终端屏幕,然后进入ns-3.21目录下的示例文件夹:
clear
cd ns-3.21
运行一个基础的示例脚本,例如hello-simulator:
./waf --run hello-simulator
该示例基于Python绑定运行。执行后,如果终端显示“Hello Simulator”等相关输出,则表明NS3安装成功。



总结 🎯



在本节课中,我们一起学习了在Linux Mint 17系统中安装NS3网络模拟器的完整步骤。我们从系统更新和安装必备开发工具开始,然后下载并解压了NS3的源代码包。接着,我们通过构建命令编译了NS3的核心模块,并最终通过运行一个简单的示例程序验证了安装是否成功。现在,您的环境已经准备就绪,可以开始探索NS3提供的各种网络模拟示例和功能了。
08:使用NS3进行TCP拥塞控制 🚦
在本节课中,我们将学习如何在网络模拟器NS3中实现和观察TCP拥塞控制机制。我们将通过分析一个现成的示例代码,了解拥塞窗口如何随时间变化,并最终通过绘图直观地展示这一过程。
概述 📋


TCP拥塞控制是确保网络稳定和高效运行的关键机制。它主要包含三个阶段:慢启动、拥塞避免和拥塞检测。在NS3中,我们可以通过模拟来观察这些阶段如何影响数据传输。
拥塞控制三阶段
以下是TCP拥塞控制的三个核心阶段:
- 慢启动:连接初始阶段,拥塞窗口大小呈指数级增长。公式表示为:
cwnd = cwnd * 2。 - 拥塞避免:当窗口大小达到慢启动阈值后,转为线性增长。公式表示为:
cwnd = cwnd + 1。 - 拥塞检测:当检测到数据包丢失(拥塞)时,窗口大小会急剧减少,通常减半。公式表示为:
cwnd = cwnd / 2。
代码结构与解析 🧩
上一节我们介绍了拥塞控制的基本概念,本节中我们来看看NS3中实现该机制的示例代码 seventh.cc 的主要结构。
该程序创建了两个节点,通过点对点链路连接,并配置了TCP协议来模拟数据传输和拥塞控制。
应用程序类:MyApp
程序定义了一个名为 MyApp 的应用程序类,它继承自 Application 类,负责在节点间发送数据包。
以下是 MyApp 类的关键方法:
Setup: 配置套接字地址、数据包大小、数量和数据速率。StartApplication: 启动应用程序,绑定套接字并连接到对等节点。ScheduleTx: 安排下一个数据包的发送时间。SendPacket: 创建并发送数据包。
跟踪与数据收集
为了观察拥塞窗口的变化,代码使用了跟踪回调函数。
static void
CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
{
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}
此函数在每次拥塞窗口变化时被调用,将时间戳、旧窗口值和新窗口值记录到文件中。
类似地,还有一个函数用于记录数据包丢失(RxDrop)事件。
主函数配置
在主函数中,程序完成了以下设置:



- 创建两个网络节点。
- 配置点对点链路的带宽(5 Mbps)和延迟(2ms)。
- 安装互联网协议栈并分配IP地址。
- 创建
MyApp应用程序实例,将其安装在发送节点(node0)上,并配置接收器在节点(node1)上。 - 连接跟踪回调函数,将拥塞窗口数据写入文件
seventh.cwnd。 - 启用PCAP跟踪,便于后续使用Wireshark分析。
- 配置GnuplotHelper,自动生成数据包计数与时间的关系图。


运行模拟与结果分析 📊







编译并运行程序后,会生成多个数据文件。我们最关心的是记录拥塞窗口变化的 seventh.cwnd 文件。


该文件包含三列数据:时间(秒)、旧拥塞窗口值、新拥塞窗口值。通过分析数据,可以清晰地看到窗口值经历指数增长、线性增长和因丢包导致的乘性减少这一循环过程。
为了更直观地展示,我们可以使用Gnuplot绘制图形。创建一个脚本文件(例如 congestion.plt):
set terminal png
set output “congestion.png”
set title “TCP Congestion Window”
set xlabel “Time (seconds)”
set ylabel “Congestion Window (bytes)”
plot “seventh.cwnd” using 1:2 with linespoints title “Old Cwnd”, \
“seventh.cwnd” using 1:3 with linespoints title “New Cwnd”




然后在终端执行 gnuplot congestion.plt,即可生成展示拥塞窗口随时间变化的PNG图像。从图中可以观察到典型的锯齿状模式,这是TCP拥塞避免算法的特征。
总结 🎯



本节课中我们一起学习了如何在NS3中模拟和分析TCP拥塞控制。我们剖析了示例代码 seventh.cc 的结构,了解了如何设置网络拓扑、应用程序以及关键的数据跟踪机制。最后,通过运行模拟并绘制拥塞窗口变化图,我们直观地验证了慢启动、拥塞避免和快速恢复等算法阶段的行为。利用NS3的这些工具,可以方便地对各种网络拥塞控制算法进行研究和性能评估。
09:MANET路由协议比较与仿真分析
在本教程中,我们将学习如何使用网络模拟器NS3来比较四种移动自组织网络路由协议:AODV、DSDV、OLSR和DSR。我们将从理解源代码开始,逐步完成仿真运行、数据提取和结果可视化。

概述
我们将使用NS3自带的示例程序 manet-routing-compare.cc 作为基础。本教程将指导你如何复制、编译并运行该程序,生成仿真数据,并使用Python和Gnuplot等工具分析结果,最终绘制出协议性能对比图。


准备工作
上一节我们介绍了本教程的目标和使用的工具。本节中,我们来看看运行此项目所需的具体环境和文件准备。
步骤1:复制源代码文件
首先,我们需要将示例文件复制到NS3的scratch文件夹中,这是运行自定义仿真的标准位置。
- 源文件路径:
ns-3.29/examples/routing/manet-routing-compare.cc - 目标路径:
ns-3.29/scratch/
步骤2:检查NS3版本与环境
确保你使用的NS3版本(例如3.29)与代码兼容。本教程在Ubuntu 18.04系统上完成。
源代码解析
上一节我们准备好了仿真文件。本节中,我们来深入理解 manet-routing-compare.cc 源代码的结构和关键部分。
该程序定义了一个名为 RoutingExperiment 的C++类来管理整个仿真实验。
核心类结构
以下是 RoutingExperiment 类的主要成员:
class RoutingExperiment
{
public:
RoutingExperiment(); // 构造函数
void Run (int nSinks, double txp, std::string CSVfileName); // 运行仿真
void CommandSetup (int argc, char **argv); // 命令行参数设置
private:
Ptr<Socket> SetupPacketReceive (Ipv4Address addr, Ptr<Node> node); // 设置数据包接收
void ReceivePacket (Ptr<Socket> socket); // 接收数据包的回调函数
void CheckThroughput (); // 计算并记录吞吐量
uint32_t port; // 端口号
uint32_t bytesTotal; // 接收的总字节数
uint32_t packetsReceived; // 接收的数据包总数
std::string m_CSVfileName; // 输出CSV文件名
int m_nSinks; // 接收节点(Sink)的数量
std::string m_protocolName; // 协议名称
double m_txp; // 发射功率
bool m_traceMobility; // 是否启用移动性追踪
};
关键参数配置
在 Run 函数中,程序设置了仿真的核心参数,我们可以根据需求修改:
nWifi = 50: 网络中的节点总数。totalTime = 200: 总仿真时间(秒)。rate = “2048bps”: 应用层数据发送速率。nodeSpeed = 20: 节点移动速度(米/秒)。nodePause = 0: 节点暂停时间(秒)。protocol = 2: 路由协议选择(1:OLSR, 2:AODV, 3:DSDV, 4:DSR)。
协议选择逻辑
程序使用一个 switch 语句来根据 protocol 变量的值选择并安装相应的路由协议:
switch (protocol)
{
case 1:
olsr.Install (); // 安装OLSR协议
break;
case 2:
aodv.Install (); // 安装AODV协议
break;
case 3:
dsdv.Install (); // 安装DSDV协议
break;
case 4:
dsrMain.Install (dsr, adhocNodes); // 安装DSR协议
break;
default:
NS_FATAL_ERROR (“No such protocol:” << protocol);
}
数据记录与输出
程序通过以下方式记录仿真数据:
- CSV文件: 记录随时间变化的吞吐量、接收包数等信息。文件名由
m_CSVfileName指定。 - FlowMonitor: 一个强大的工具,能生成包含流统计信息(如延迟、丢包率)的XML文件。要使用它,需要在源代码头部添加包含语句:
#include “ns3/flow-monitor-helper.h” - Mobility Trace: 如果启用 (
m_traceMobility=true),会生成记录节点移动轨迹的文件。 - ASCII Trace: 可生成详细的底层收发事件记录文件(
.tr),用于深度分析。
运行仿真与数据分析

上一节我们详细分析了源代码。本节中,我们来看看如何编译、运行仿真并处理生成的数据。
步骤3:编译与运行仿真
在NS3根目录(ns-3.29)下打开终端,执行以下命令来运行仿真:


./waf --run scratch/manet-routing-compare
仿真运行需要一些时间(约数分钟),完成后会在当前目录生成输出文件。


步骤4:处理FlowMonitor XML文件
仿真会生成一个 .flowmon 文件(例如 AODV.flowmon)。我们可以使用Python脚本解析此文件并绘制图表。



以下是处理FlowMonitor数据的Python脚本核心逻辑:
import xml.etree.ElementTree as ET
import matplotlib.pyplot as plt
tree = ET.parse(‘AODV.flowmon’) # 解析XML文件
root = tree.getroot()


flow_ids = []
bitrates = []
lost_packets = []
delays = []


for flow in root.findall(‘FlowStats/Flow’):
# 提取每个流的数据
tx_packets = float(flow.get(‘txPackets’))
rx_packets = float(flow.get(‘rxPackets’))
delay_sum = float(flow.get(‘delaySum’)[:-1]) # 去除’ns‘单位
lost_packets.append(tx_packets - rx_packets)
# … 计算比特率、延迟等 …
bitrates.append(bitrate)
delays.append(delay)
# 使用matplotlib绘制图表
plt.figure()
plt.subplot(311)
plt.plot(flow_ids, bitrates, ‘ro’)
plt.ylabel(‘Bitrate (bps)’)
# … 绘制其他子图,如丢包数、延迟 …
plt.savefig(‘results.png’)


运行脚本:
python flow_analysis.py AODV.flowmon


步骤5:处理CSV文件并比较协议性能
仿真生成的CSV文件(如 AODV.csv)包含时间、接收速率和接收包数。我们可以使用Gnuplot绘制曲线图。

首先,整理CSV文件,将逗号分隔符替换为空格。然后,创建Gnuplot脚本(plot.gnuplot):

set terminal png
set output “comparison.png”
set title “接收速率对比”
set xlabel “仿真时间 (秒)”
set ylabel “接收速率”
plot “AODV.csv” using 1:2 with lines title “AODV”, \
“OLSR.csv” using 1:2 with lines title “OLSR”


运行Gnuplot脚本:
gnuplot plot.gnuplot
这将生成一个名为 comparison.png 的图片,直观显示AODV和OLSR协议在接收速率上的性能差异。


步骤6:使用TraceMatric分析详细跟踪文件



如果启用了ASCII Trace,会生成 .tr 文件。可以使用Java工具 TraceMatric 来图形化分析这个包含大量底层事件的文件。

- 确保已安装Java。
- 下载TraceMatric的JAR文件及其库。
- 运行命令打开图形界面:
java -jar tracematric.jar - 在界面中选择生成的
.tr文件进行分析,可以查看各种事件的统计和时序图。


总结



在本教程中,我们一起学习了如何使用NS3对MANET路由协议(AODV、DSDV、OLSR、DSR)进行性能比较仿真。我们从理解源代码结构开始,逐步完成了仿真环境的配置、程序的编译运行,以及利用Python、Gnuplot和TraceMatric等工具对仿真生成的FlowMonitor XML文件、CSV数据文件和详细跟踪文件进行多维度分析及可视化。通过修改源代码中的节点数、移动速度、协议类型等参数,你可以进一步探索不同网络场景下各协议的性能表现,为学术研究或项目开发提供数据支持。
10:使用ns3进行VANET路由 - 第一部分 🚗
在本节课中,我们将学习如何使用ns-3模拟器来研究车载自组织网络中的路由协议。我们将重点分析一个名为 vanet-routing-compare.cc 的示例,该示例允许我们比较不同的路由协议在车辆网络环境中的性能。
概述


本教程将分为三个主要步骤。首先,我们将详细解释源代码的结构和功能。其次,我们将学习如何利用OpenStreetMap创建一个真实的交通场景。最后,我们将对多种路由协议进行性能分析。本示例代码超过1500行,我们将分块进行讲解,以便于理解。
源代码解释
上一节我们介绍了本教程的整体结构,本节中我们来看看源代码的具体实现。
源代码位于 ns-3.27/scratch/ 目录下的 vanet-routing-compare.cc 文件。为了确保所有模块都能正确加载,建议将此文件移动到 scratch 文件夹中运行。
该示例用于运行车辆自组织网络仿真场景。它使用了802.11p MAC层协议,这是一种专为车联网设计的无线接入标准。传播损耗模型支持自由空间、双射线地面和ITU模型。应用层流量使用基本安全消息(BSM),我们可以观察安全消息的包投递率。路由协议方面,可以比较DSDV、AODV、OLSR和DSR。默认情况下,程序使用AODV协议。
仿真场景可以是使用随机路点移动模型生成的合成高速公路场景,也可以是通过回放移动轨迹文件(.tcl文件)创建的真实场景。脚本允许修改许多参数,例如,一个场景可以运行10秒,包含40个节点,以20米/秒的速度在300x1500米的区域内移动,Wi-Fi使用10MHz的控制信道。
核心类与函数
以下是源代码中定义的主要类及其功能:
- RoutingStats类:用于统计路由信息,例如接收/发送的字节数和包数。其构造函数将所有计数器初始化为0。
RoutingStats::RoutingStats () : m_RxBytes (0), m_cumulativeRxBytes (0), m_RxPkts (0), ... { } - RoutingHelper类:帮助安装和配置路由协议。它可以根据参数安装不同的协议(1=OLSR, 2=AODV, 3=DSDV, 4=DSR)。
- WifiPhyStats类:用于收集Wi-Fi物理层的统计信息,如丢包数。
- VanetRoutingExperiment类:继承自
WifiApp类,是主要的实验类。它包含了设置节点、信道、设备、移动性、应用程序、跟踪以及运行仿真的所有函数。
关键配置参数
在 VanetRoutingExperiment 类的构造函数中,设置了许多默认参数:
port: 9CSVfileName: "vanet-routing-output.csv"nSinks: 10protocol: 2 (代表AODV)traceMobility: falselossModel: 3phyMode: "OfdmRate6MbpsBW10MHz"80211Mode: 1 (代表802.11p)nNodes: 156totalTime: 300 秒rate: "2048bps"nodeSpeed: 20 m/snodePause: 0wavePacketSize: 200 字节


此外,还定义了安全消息的传输范围(50米到500米,每50米一个间隔),用于计算不同距离下的包投递率。
命令参数覆盖
程序支持通过命令行参数覆盖默认值,这为灵活实验提供了便利。例如:
- 要改变仿真总时间:
--TotalTime=10 - 要改变使用的路由协议:
--protocol=4(使用DSR) - 要改变节点数量:
--nNodes=50
运行示例与初步分析
上一节我们剖析了代码结构,本节中我们来看看如何运行示例并进行初步结果分析。
首先,将 vanet-routing-compare.cc 文件复制到 scratch 目录并编译运行。默认情况下,它使用AODV协议运行一个10秒的简短场景。


我们可以通过命令行参数运行不同协议的仿真进行比较:
- AODV (默认):
./waf --run "scratch/vanet-routing-compare --protocol=2" - OLSR:
./waf --run "scratch/vanet-routing-compare --protocol=1" - DSDV:
./waf --run "scratch/vanet-routing-compare --protocol=3" - DSR:
./waf --run "scratch/vanet-routing-compare --protocol=4" - 无路由协议:
./waf --run "scratch/vanet-routing-compare --protocol=0"
运行后,终端会输出关键性能指标,例如不同距离(50m, 100m, ..., 500m)下的BSM包投递率(PDR)和网络总吞吐量(Goodput)。初步观察显示,在本示例的短时仿真中,DSR协议的吞吐量表现最佳。


生成的文件
仿真运行后会生成多个文件,用于进一步分析:
vanet-routing-compare.mob: 节点移动轨迹文件,记录每个时间点节点的位置和速度。vanet-routing-output.csv和vanet-routing-output2.csv: 主要的性能指标CSV文件,包含每秒的接收包数、发送包数、投递率等详细数据。vanet-animation.xml: 网络动画文件,可通过NetAnim工具可视化仿真过程。.pcap文件: 如果启用,会生成数据包捕获文件,可用于Wireshark分析。
网络动画可视化

通过修改源代码,在仿真运行前添加网络动画接口,可以生成 .xml 动画文件。使用NetAnim工具打开此文件,可以直观地观察车辆节点的移动和它们之间的数据包交换过程。这对于理解网络动态和调试非常有帮助。

总结


本节课中我们一起学习了ns-3中VANET路由比较示例的第一部分。我们详细解读了超过1500行的源代码结构,了解了如何配置车辆网络仿真参数,以及如何运行仿真来比较AODV、OLSR、DSDV和DSR等路由协议。我们还看到了如何通过命令行覆盖默认参数,并初步查看了仿真输出的结果文件和简单的网络动画。




在接下来的第二部分,我们将深入探讨如何利用SUMO(Simulation of Urban Mobility)和OpenStreetMap创建更真实的城市交通场景,并详细分析生成的CSV数据,绘制如吞吐量、时延、包投递率等关键性能指标的图表,从而完成完整的VANET路由协议性能评估。
11:使用Gnuplot绘制直方图 📊

在本节课中,我们将学习如何使用Gnuplot工具绘制直方图。直方图是数据可视化的重要方式,能够直观地展示数据的分布情况。我们将从创建数据文件开始,逐步编写Gnuplot脚本,最终生成清晰的直方图。
概述
本节课是Gnuplot系列教程的第二部分,重点介绍直方图的绘制方法。我们将使用一个关于全球主要城市空气质量指数的数据集作为例子,演示如何创建数据文件、编写Gnuplot脚本,并生成包含多个数据系列的直方图。
第一步:创建数据文件
绘制直方图的第一步是准备数据。我们将创建一个文本文件,其中包含城市名称以及对应的空气质量指数数据。以下是数据文件的示例内容:
Chennai 323 278
Turkey 93 89
Andorra 7 7
Palestine 70 67
Bulgaria 159 123
China 6 8
Netherlands 52 76
在这个例子中,第一列是城市名称,第二列是本周的空气质量指数,第三列是上周的空气质量指数。我们将这个文件保存为 aqi.data。
第二步:编写Gnuplot脚本
接下来,我们需要编写一个Gnuplot脚本来绘制直方图。脚本将指定输出格式、图表标题、样式以及要绘制的数据列。
以下是脚本的基本结构:
set terminal pdf
set output "aqi.pdf"
set title "Air Quality Index"
set style data histogram
set style histogram clustered
plot "aqi.data" using 2:xtic(1) title "This Week", \
"" using 3 title "Last Week"
在这个脚本中:
set terminal pdf指定输出格式为PDF。set output "aqi.pdf"设置输出文件名。set title "Air Quality Index"设置图表标题。set style data histogram指定使用直方图样式。set style histogram clustered指定使用簇状直方图。plot命令用于绘制数据,using 2:xtic(1)表示使用第二列数据,并将第一列作为X轴标签。
第三步:运行脚本并查看结果
将脚本保存为 gnuplot_script.txt,然后在终端中运行以下命令:
gnuplot gnuplot_script.txt
运行后,将生成一个名为 aqi.pdf 的PDF文件,其中包含绘制的直方图。您可以使用PDF查看器打开文件,检查图表的显示效果。
第四步:优化直方图样式
默认生成的直方图可能没有填充颜色,看起来不够直观。我们可以通过添加 set style fill solid 命令来为直方图填充颜色:


set style fill solid
更新脚本后,再次运行Gnuplot命令,生成的直方图将具有填充颜色,更加清晰易读。


第五步:旋转X轴标签
如果城市名称较长,可能会导致X轴标签重叠。我们可以通过旋转X轴标签来解决这个问题:


set xtic rotate out
添加这行命令后,X轴标签将以垂直方向显示,避免重叠。
第六步:在同一文件中包含数据
除了将数据保存在单独的文件中,我们还可以将数据直接嵌入Gnuplot脚本。以下是示例:
set terminal pdf
set output "aqi_embedded.pdf"
set title "Air Quality Index"
set style data histogram
set style fill solid
set xtic rotate out
plot "-" using 2:xtic(1) title "AQI"
Delhi 100
Chennai 88
Mumbai 87
Pune 67
Madrid 90
e
在这个脚本中,plot "-" 表示数据来自脚本内部。数据行以 e 结束。这种方式适用于数据量较小的情况。
总结
本节课中,我们一起学习了如何使用Gnuplot绘制直方图。我们从创建数据文件开始,逐步编写了Gnuplot脚本,并通过优化样式和旋转标签提升了图表的可读性。最后,我们还介绍了如何将数据直接嵌入脚本中。掌握这些技巧后,您可以根据自己的需求绘制各种直方图,更好地展示和分析数据。

希望本节课对您有所帮助!如果您有任何问题或建议,请在评论区留言。感谢观看!
12:Trace Metrics与Ascii Trace 📊









在本节课中,我们将学习如何在NS3中启用Ascii Trace(ASCII跟踪)功能,并使用Trace Matrix软件来分析生成的跟踪文件,从而获取网络性能指标,如吞吐量、有效吞吐量、延迟和丢包率等。




概述
上一节我们介绍了如何运行一个基本的NS3仿真。本节中,我们来看看如何启用详细的跟踪功能,并利用外部工具对仿真数据进行可视化分析。我们将重点学习Ascii Trace的启用方法以及Trace Matrix软件的使用。


启用Ascii Trace

为了生成可供分析的跟踪文件,我们需要在NS3源代码中启用Ascii Trace功能。这主要涉及两个部分:节点移动性跟踪和Wi-Fi物理层信道跟踪。

以下是需要在仿真脚本中添加的核心代码:
// 启用移动性跟踪
AsciiTraceHelper ascii;
MobilityHelper mobility;
mobility.EnableAsciiAll (ascii.CreateFileStream ("manet-trace.mob"));
// 启用Wi-Fi物理层跟踪
WifiPhyHelper wifiPhy;
wifiPhy.EnableAsciiAll (ascii.CreateFileStream ("manet-trace.tr"));
代码解释:
AsciiTraceHelper和MobilityHelper类用于创建节点移动轨迹的跟踪文件(扩展名为.mob)。WifiPhyHelper类用于创建Wi-Fi物理层信道活动的跟踪文件(扩展名为.tr)。- 执行仿真后,这两个文件将出现在你的工作目录中。
修改代码后,需要重新编译并运行仿真以生成跟踪文件。
安装Trace Matrix软件




为了分析生成的 .tr 跟踪文件,我们需要使用一个名为Trace Matrix的专用软件。该软件是一个Java应用程序。


以下是安装步骤:
- 从官方网站下载Trace Matrix的JAR文件。
- 确保系统已安装Java运行环境(JRE)。可以通过命令
java -version检查。 - 将下载的JAR文件解压到一个文件夹中。
使用Trace Matrix分析数据
Trace Matrix可以解析NS3生成的Ascii Trace文件,并计算出多种性能指标。
以下是使用Trace Matrix的基本流程:
- 在终端中,导航到包含Trace Matrix JAR文件的目录。
- 使用命令
java -jar trace-matrix.jar启动软件。 - 在软件界面中,打开由NS3生成的
.tr文件。 - 软件将自动分析文件,并显示摘要信息,如总数据包数、发送/接收/丢弃的数据包数量、总仿真时间等。

关键性能指标
通过Trace Matrix,我们可以获取并导出以下几类核心性能指标:

1. 吞吐量与有效吞吐量
- 吞吐量:指通过某个节点的总数据速率(包括中转数据)。计算公式可简化为:
总字节数 / 仿真时间。 - 有效吞吐量:指成功送达最终目的地的应用层数据速率。它衡量的是网络对用户“有用”的吞吐量。

在Trace Matrix的“Throughput & Goodput”选项卡中,可以查看每个节点的这两项数据,并导出为数据文件用于绘图。
2. Lambda因子(平均包速率)
Lambda因子表示每个节点在仿真期间的平均每秒数据包数量。它反映了节点的活跃程度。该数据可以在“Lambda”选项卡中查看和导出。


3. 延迟变化
在“Delay Variation”选项卡中,可以分析UDP流的端到端延迟变化情况。软件支持生成线性或对数坐标的图形,并能导出Gnuplot脚本,以便生成高质量的矢量图(如PDF)。
4. 接收速率与丢包率
软件还能提供数据包接收速率以及数据包丢弃(通常由于队列满导致)的统计信息,帮助评估网络拥塞情况。
数据可视化


导出的数据文件(如吞吐量、Lambda值)可以使用Gnuplot等工具进行可视化。

以下是一个使用Gnuplot绘制吞吐量和有效吞吐量对比图的示例脚本:
set terminal png size 1200,800
set output "throughput-goodput.png"
set title "Throughput vs Goodput per Node"
set xlabel "Node Number"
set ylabel "Rate (bytes/sec)"
plot "throughput-goodput.data" using 1:2 with linespoints title "Throughput", \
"" using 1:3 with linespoints title "Goodput" lw 2
执行此脚本将生成一个PNG图像,清晰地展示每个节点的吞吐量与有效吞吐量的差异。
总结
本节课中我们一起学习了NS3中性能分析的重要环节。
- 我们首先学习了如何在仿真脚本中启用Ascii Trace功能,以生成详细的移动性和物理层跟踪文件。
- 接着,我们介绍了如何使用Trace Matrix这款Java软件来加载和分析
.tr跟踪文件。 - 最后,我们探讨了如何利用该软件提取并可视化关键的网络性能指标,包括吞吐量、有效吞吐量、包速率和延迟变化。

掌握这些技能,你就能对NS3仿真结果进行定量分析,从而更科学地评估和比较不同网络协议或配置的性能。
13:NS3中的流监控器(Flow Monitor)📊
在本节课中,我们将学习如何在NS3网络模拟器中使用流监控器(Flow Monitor)来监控和分析网络性能。流监控器是一个强大的工具,可以生成详细的XML报告,帮助我们计算诸如延迟、抖动、丢包率、吞吐量等多种网络性能指标。
概述
流监控器是NS3提供的一个组件,用于监控网络中的数据流。它可以生成一个XML文件,其中包含了每个数据流的详细统计信息。通过分析这个文件,我们可以评估网络的整体性能。

上一节我们介绍了网络模拟的基础,本节中我们来看看如何使用流监控器来量化网络性能。



第一步:准备示例文件
首先,我们需要将NS3自带的两个示例脚本复制到scratch目录下,以便进行修改和实验。
以下是需要复制的文件:
examples/tutorial/third.ccexamples/routing/manet-routing-compare.cc
你可以通过终端命令或图形界面文件管理器来完成复制操作。
第二步:在代码中添加流监控器
为了在模拟中使用流监控器,我们需要在源代码中包含必要的头文件并添加几行初始化代码。

需要包含的头文件是:
#include “ns3/flow-monitor.h”
#include “ns3/flow-monitor-helper.h”


接着,在模拟代码中(通常在调用Simulator::Run()之前),添加以下代码来创建和安装流监控器:

// 创建流监控器对象
Ptr<FlowMonitor> flowMonitor;
FlowMonitorHelper flowHelper;
flowMonitor = flowHelper.InstallAll();

最后,在模拟运行结束之后(Simulator::Run()之后),添加代码将监控结果写入XML文件:



flowMonitor->SerializeToXmlFile(“你的文件名.xml”, true, true);

例如,在third.cc中,我们可以将文件名设置为third.xml。
第三步:编译并运行示例

完成代码修改后,我们需要编译并运行脚本以生成包含流监控数据的XML文件。
使用以下命令编译并运行third.cc示例:
./waf --run scratch/third
运行成功后,你会在当前目录下找到生成的XML文件(如third.xml)。这个文件包含了模拟过程中所有数据流的详细记录。
第四步:解析与分析XML文件
生成了XML文件后,我们需要解析它以获取有意义的性能指标。NS3自带了一个Python脚本flowmon-parse-results.py,可以帮助我们进行初步分析。
首先,找到该脚本的位置(通常在src/flow-monitor/examples/目录下),并将其复制到你的工作目录。然后使用以下命令解析XML文件:


python flowmon-parse-results.py third.xml




该脚本会输出每个流的统计摘要,例如平均延迟、发送/接收的比特数和包数等。



第五步:使用Python脚本进行可视化

为了更直观地分析性能,我们可以编写Python脚本,利用matplotlib库将数据绘制成图表。脚本的核心逻辑是解析XML文件,提取关键指标(如比特率、延迟、丢包数),然后将它们绘制出来。
以下是一个简化的脚本结构示例:
import xml.dom.minidom
import sys
import matplotlib.pyplot as plt

# 初始化列表来存储数据
bitrates = []
losses = []
delays = []
# 解析XML文件
DOMTree = xml.dom.minidom.parse(“third.xml”)
collection = DOMTree.documentElement
# 遍历XML中的每个“Flow”元素,提取数据并添加到列表中
flows = collection.getElementsByTagName(“Flow”)
for flow in flows:
# 提取 txBytes, rxBytes, delaySum 等属性值
# 计算比特率、丢包率、平均延迟
# bitrates.append(calculated_bitrate)
# losses.append(calculated_loss)
# delays.append(calculated_delay)
pass



# 使用matplotlib绘制图表
fig, axs = plt.subplots(3)
axs[0].plot(bitrates, ‘b-‘)
axs[0].set_title(‘Flow Bit Rates’)
# … 设置其他子图
plt.tight_layout()
plt.savefig(‘results.pdf’)
plt.show()
运行此脚本将生成一个PDF文件,其中包含了比特率、丢包和延迟随数据流变化的曲线图。


第六步:分析复杂网络场景
为了观察更真实的网络性能,我们可以对更复杂的示例(如manet-routing-compare.cc)应用相同的流监控步骤。这个脚本模拟了移动自组织网络(MANET)中的多种路由协议,会产生更大量的数据流和更丰富的性能变化。

按照第二、三步修改、编译并运行该示例,生成XML报告文件(例如manet.xml)。然后使用第四、五步的方法进行解析和可视化分析。在复杂的场景中,你可能会观察到更高的延迟变化、更多的丢包以及不同流之间比特率的显著差异。




总结


本节课中我们一起学习了NS3中流监控器(Flow Monitor)的使用方法。我们从准备示例文件开始,逐步完成了在代码中集成监控功能、运行模拟生成数据、解析XML报告,到最后使用Python进行数据可视化的全过程。流监控器是评估网络协议和拓扑性能的利器,掌握它对于进行深入的网络仿真研究至关重要。通过分析生成的图表,我们可以直观地比较不同网络配置下的性能优劣。
14:VANETs中的路由 - 第二部分 🚗


在本节课中,我们将学习如何分析在VANETs(车载自组织网络)路由模拟中生成的结果。我们将使用SUMO生成真实交通场景,将其转换为ns-3可用的移动性文件,运行模拟,并最终评估和可视化不同路由协议的性能指标。


上一节我们介绍了如何在ns-3中设置和运行VANET路由模拟。本节中,我们来看看如何生成模拟数据并对其进行分析。
步骤一:使用SUMO生成交通场景 🗺️







首先,我们需要使用SUMO生成一个真实的交通移动性场景。



以下是生成交通场景的步骤:





- 导航到SUMO的
tools目录。 - 运行
osmWebWizard.py脚本以打开浏览器配置界面。python osmWebWizard.py - 在浏览器界面中,选择你希望模拟的地理区域。建议选择一个较小的区域以减少计算负载。
- 配置交通参数,例如车辆类型(小汽车、卡车、公交车)和交通密度(车辆数/小时/公里)。
- 设置模拟持续时间(例如100秒)。
- 点击“生成场景”并下载生成的文件。






运行结束后,你会在tools目录下得到一个以日期和时间命名的文件夹,其中包含sumo-config.sumocfg等配置文件。你可以使用以下命令在SUMO GUI中查看生成的交通流:
sumo-gui sumo-config.sumocfg



步骤二:将SUMO轨迹转换为ns-3移动性文件 🔄

SUMO生成的轨迹需要转换为ns-3能够识别的移动性跟踪文件。




以下是转换步骤:
- 首先,将SUMO配置转换为浮动车辆数据(FCD)跟踪文件。
此命令会生成一个包含所有车辆移动详细信息的sumo -c osm.sumocfg --fcd-output trace.xmltrace.xml文件。 - 接着,使用SUMO工具
traceExporter.py将FCD跟踪文件转换为ns-3的移动性跟踪文件(.tcl格式)。
请确保正确设置SUMO_HOME环境变量,以便脚本能找到所需模块。python traceExporter.py --fcd-input trace.xml --ns2mobility-output mobility.tcl - 转换完成后,打开
mobility.tcl文件,记录关键信息,例如节点总数和模拟总时间。这些信息在后续的ns-3脚本配置中至关重要。
步骤三:在ns-3中运行路由模拟 ⚙️
现在,我们将使用转换好的移动性文件在ns-3中运行路由比较模拟。
以下是运行模拟的步骤:
- 将ns-3示例目录中的路由比较脚本(例如
routing-compare.cc)复制到你的scratch目录。 - 使用文本编辑器打开该脚本,修改关键参数以匹配你的场景:
totalNodes: 设置为mobility.tcl中的节点总数(例如32)。totalTime: 设置模拟时间(例如30或100秒)。nodeSpeed: 设置节点速度(例如20 m/s)。traceFile: 指向你生成的mobility.tcl文件的路径。- 配置输出日志文件的名称。
- 在终端中,使用不同的协议标识符多次运行该脚本,以比较多种路由协议(如OLSR、AODV、DSDV、DSR)。
./waf --run "scratch/routing-compare --protocol=1" # OLSR ./waf --run "scratch/routing-compare --protocol=2" # AODV ./waf --run "scratch/routing-compare --protocol=3" # DSDV ./waf --run "scratch/routing-compare --protocol=4" # DSR - 每次运行都会生成对应的输出文件(如
OLSR.csv,AODV.csv),其中包含了各种性能指标的数据。
步骤四:分析性能指标与结果可视化 📊
模拟运行完成后,我们可以提取关键性能指标并进行可视化比较。
我们将关注以下几个核心指标:
- 分组投递率 (PDR): 成功接收的分组数与发送分组总数之比。
- 吞吐量 (Goodput): 应用层实际接收的有效数据速率。
- MAC/PHY层开销 (Overhead): 控制信息等开销所占的比例。
- 接收速率 (Receive Rate): 单位时间内接收的分组数。
以下是分析步骤:


- 提取数据:从每个协议的
.csv输出文件中,提取你关心的指标数据(例如吞吐量和MAC开销)。 - 使用电子表格软件:将提取的数据(例如OLSR、AODV、DSDV、DSR的吞吐量)粘贴到如LibreOffice Calc或Microsoft Excel中。
- 选中数据列。
- 插入图表(如柱状图)。
- 为图表添加标题、X轴(协议名称)和Y轴(指标名称,如“吞吐量 (Kbps)”)。
- 使用Gnuplot进行高级绘图:对于随时间变化的指标(如接收速率),使用Gnuplot可以绘制更精细的曲线图。
- 创建一个Gnuplot脚本文件(例如
plot_rr.gp)。 - 在脚本中设置图形标题、坐标轴标签,并绘制多个数据文件。
set title \"接收速率对比\" set xlabel \"模拟时间 (秒)\" set ylabel \"接收速率 (分组/秒)\" plot \"OLSR.csv\" using 1:2 with linespoints title \"OLSR\", \\ \"AODV.csv\" using 1:2 with linespoints title \"AODV\", \\ \"DSDV.csv\" using 1:2 with linespoints title \"DSDV\", \\ \"DSR.csv\" using 1:2 with linespoints title \"DSR\" - 在终端运行该脚本:
gnuplot plot_rr.gp。
- 创建一个Gnuplot脚本文件(例如
- 结果解读:通过对比图表,可以直观地分析哪种协议在你的特定场景(节点数、移动性、时间)下表现更优。例如,你可能会发现DSR协议的开销最低,而AODV的吞吐量在某些时段较高。


总结 🎯



本节课中我们一起学习了VANET路由模拟结果分析的完整流程。我们从使用SUMO生成真实交通移动性开始,将其转换为ns-3格式,然后运行了多种路由协议的对比模拟,最后提取关键性能指标并利用电子表格和Gnuplot工具进行了可视化分析。这套方法使你能够系统地评估不同网络协议在动态车载环境下的性能,为深入研究或项目开发奠定了基础。在接下来的课程中,我们将探索如何使用Flow Monitor等更强大的工具来深入分析网络流量的细节。
15:使用NS3和SUMO进行VANET仿真 🚗
在本节课中,我们将学习如何使用网络模拟器NS3和交通模拟器SUMO来创建一个车辆自组织网络仿真场景。我们将通过一个具体的例子,演示如何从生成交通场景到在NS3中运行仿真的完整流程。
概述

VANET仿真结合了交通流动态和网络通信行为。本节教程将分步指导您如何利用SUMO生成真实的城市交通数据,并将其转换为NS3可用的节点移动性模型,最终在NS3中运行并可视化仿真。

步骤一:使用SUMO生成交通场景 🗺️
首先,我们需要使用SUMO软件生成一个基础的交通仿真场景。SUMO提供了多种方式创建场景,本教程将使用其内置的Web向导工具,这是一种快速生成交通场景的简便方法。



注意:请确保您已从源代码编译安装了SUMO(例如1.2.x版本),而不是通过简单的apt install命令安装,以便能够使用所有扩展功能。







以下是生成场景的具体操作:
- 进入SUMO的
tools目录。 - 运行Web向导Python脚本。
cd sumo/tools python3 sumo-web-wizard.py - 脚本将自动打开浏览器窗口,显示地图界面。
- 在地图上选择或搜索您想要仿真的区域(例如“Chennai”)。建议选择较小的区域以降低后续处理的复杂度。
- 在右侧面板中,自定义仿真的车辆类型和数量,例如小汽车、公交车、摩托车等。
- 点击“Generate Scenario”按钮,SUMO将生成配置文件并自动打开
sumo-gui可视化界面。 - 在
sumo-gui中,您可以调整仿真延迟(如设为30毫秒以更接近实时),然后运行仿真,观察交通流的运行情况。

完成此步骤后,SUMO会在特定目录(通常以时间戳命名)下生成一系列配置文件,其中sumo.cfg文件对我们至关重要。

步骤二:创建移动性轨迹文件 📁
上一节我们生成了交通场景,本节中我们来看看如何将这些数据转换为NS3能够理解的节点移动轨迹。
我们需要将SUMO的输出转换为两种格式:供NS3读取的移动性跟踪文件,以及供网络动画工具NetAnim使用的XML文件。

操作流程如下:
-
生成
trace.xml文件:使用sumo命令处理上一步生成的sumo.cfg配置文件,输出详细的轨迹XML文件。sumo -c sumo.cfg --fcd-output trace.xml此命令可能会产生一些警告信息,通常可以忽略。生成的
trace.xml文件包含了所有车辆在每个时间步的位置信息。 -
转换为NS2格式的移动性文件:SUMO的
tools目录下提供了traceExporter.py工具,可以将trace.xml转换为NS3兼容的NS2格式移动性文件。cd sumo/tools python3 traceExporter.py -i trace.xml --ns2mobility-output=mobility.tcl执行后,将得到
mobility.tcl文件。您需要打开此文件,查找并记录其中的节点总数(例如$node_(1813)表示有1813个节点),这个数字在下一步中需要用到。

- 移动文件:为了便于NS3访问,建议将生成的
mobility.tcl文件移动到您的NS3工作目录或Home目录下。


步骤三:运行NS2移动性跟踪示例 🏃♂️

现在,我们已经有了描述车辆移动的轨迹文件。接下来,需要在NS3中运行一个示例程序来加载这些数据,并验证其是否正确。
NS3源码中提供了一个名为ns2-mobility-trace的示例程序,位于src/mobility/examples/目录下。我们需要将其复制到scratch目录并运行。
具体步骤如下:
- 将
ns2-mobility-trace.cc示例文件复制到NS3的scratch目录。cp src/mobility/examples/ns2-mobility-trace.cc scratch/ - 进入NS3主目录,使用
waf命令运行该程序。命令格式需要指定轨迹文件路径、节点数量、仿真时长和日志文件名。./waf --run "scratch/ns2-mobility-trace --traceFile=/path/to/mobility.tcl --nodeNum=1813 --duration=100 --logFile=ns2-mob.log"--traceFile:指定mobility.tcl文件的完整路径。--nodeNum:填入第二步中查到的节点总数。--duration:设置仿真时长(秒)。--logFile:指定运行日志的输出文件名。


程序运行后,会在终端打印每个节点的位置和速度信息。运行完毕会生成日志文件,表明移动性数据已成功导入NS3。



步骤四:集成网络动画并运行完整仿真 🎬



最后一步,我们将修改上一步使用的示例代码,为其添加网络动画支持,从而能够可视化地观察车辆的移动过程。
我们需要在scratch/ns2-mobility-trace.cc源代码中添加NetAnim相关的代码。
修改方法如下:



- 在源代码文件开头添加NetAnim的头文件。
#include "ns3/netanim-module.h" - 在主函数
main()中,在Simulator::Run();语句之前,添加以下代码来设置动画接口并指定输出文件。AnimationInterface anim ("vehicular-mobility.xml"); - 修改后的代码结构大致如下:
// ... 其他头文件 ... #include "ns3/netanim-module.h" int main (...) { // ... 原有的节点创建、移动性模型设置等代码 ... // 添加NetAnim设置 AnimationInterface anim ("vehicular-mobility.xml"); Simulator::Run (); Simulator::Destroy (); return 0; } - 保存文件后,重新使用与步骤三相同的
waf命令编译运行程序。
此次运行除了之前的日志,还会生成一个名为./waf --run "scratch/ns2-mobility-trace --traceFile=/path/to/mobility.tcl --nodeNum=1813 --duration=100 --logFile=ns2-mob.log"vehicular-mobility.xml的动画文件。

- 使用NetAnim查看动画:
- 进入NS3的
netanim目录。 - 运行NetAnim应用程序。
- 在NetAnim界面中,通过
File->Open选择刚才生成的vehicular-mobility.xml文件。 - 您可以调整节点显示大小,然后播放动画,观察车辆节点的移动情况。
- 进入NS3的

总结

本节课中我们一起学习了使用NS3和SUMO进行VANET仿真的完整工作流程。我们首先利用SUMO的Web向导生成了一个基于真实地图的交通场景,然后通过工具将交通数据转换为NS3可用的移动性轨迹文件。接着,我们运行NS3的示例程序加载该文件,并最终通过集成NetAnim模块,实现了仿真过程的可视化。这个流程为分析VANET环境下的网络协议性能奠定了坚实的基础。您可以在此基础上,进一步集成网络协议栈,使用Wireshark或流量监测矩阵等工具来分析网络性能。
16:在Ubuntu中安装SUMO 1.2.0 🚗
概述
在本节课中,我们将学习如何在Ubuntu操作系统中安装SUMO(Simulation of Urban Mobility)软件。SUMO是一款用于交通建模、车辆连通性和网络建模的强大工具。我们将重点介绍从源代码编译安装的方法,以便未来能够扩展和使用SUMO的各种软件包。
安装步骤总览
安装过程主要分为五个步骤:
- 安装必要的依赖软件(Prerequisites)。
- 从GitHub下载SUMO源代码。
- 设置环境变量路径。
- 使用CMake进行编译配置。
- 执行编译和安装。
接下来,我们将详细讲解每一个步骤。
第一步:安装依赖软件
首先,我们需要更新系统软件包列表并安装SUMO编译所需的所有依赖项。以下是需要安装的软件包列表:
cmakepythong++libxml2-devlibfox-1.6-devlibgdal-devlibproj-devlibgl2ps-devswig
您可以使用以下命令一次性安装它们:
sudo apt update
sudo apt install cmake python g++ libxml2-dev libfox-1.6-dev libgdal-dev libproj-dev libgl2ps-dev swig
此过程大约会下载800MB的数据。安装完成后,我们就可以进行下一步了。
第二步:下载SUMO源代码
上一节我们安装了所有必要的依赖项,本节我们将从GitHub获取SUMO的源代码。
在下载之前,请确保您的系统已经安装了git工具。如果没有,请先运行:
sudo apt install git
安装好git后,使用以下命令克隆SUMO的仓库。--recursive参数确保所有子模块和文件都会被完整下载。
git clone --recursive https://github.com/eclipse/sumo
命令执行后,会在当前目录下创建一个名为sumo的文件夹,其中包含了SUMO的全部源代码、工具(tools)和数据(data)目录,这些在后续使用中非常重要。
第三步:设置环境变量
源代码下载完成后,我们需要设置一个重要的环境变量SUMO_HOME,它指向SUMO的根目录,许多SUMO工具在运行时需要这个变量。
设置方法如下,请确保您在包含sumo文件夹的目录下执行:
export SUMO_HOME="$PWD/sumo"
这条命令将当前目录下的sumo文件夹路径赋值给SUMO_HOME变量。
第四步:配置编译环境
设置好路径后,我们需要为编译创建一个独立的构建目录,并使用CMake生成编译配置文件。
进入SUMO源代码目录,并创建一个build文件夹:
cd sumo
mkdir build
cd build
然后,运行CMake命令来配置项目。..表示配置文件位于上一级目录(即sumo根目录)。
cmake ..
如果所有依赖项都已正确安装,此命令应能顺利完成,不会报错。这为下一步的实际编译做好了准备。
第五步:编译与安装
配置成功后,就可以开始编译SUMO了。我们使用make命令进行编译。

为了加快编译速度,可以利用多核处理器。-j参数后的数字表示并行编译的任务数,通常设置为处理器核心数的2倍。例如,对于4核机器,可以使用:
make -j8
如果您不确定,也可以直接使用make命令,但编译时间会更长。
编译过程需要一些时间。完成后,您会在build/bin目录下看到生成的可执行文件,如sumo和sumo-gui。


验证安装与设置永久路径
编译安装完成后,让我们来验证一下。进入二进制文件目录并运行SUMO查看版本:
cd bin
./sumo --version
您应该能看到类似SUMO 1.2.0的版本信息。同样,可以检查sumo-gui。
目前,我们只能在bin目录下通过./sumo运行。为了方便在任何地方都能使用sumo命令,需要将其路径添加到系统的PATH环境变量中。

编辑用户主目录下的shell配置文件(例如~/.bashrc):
nano ~/.bashrc
在文件末尾添加以下两行,请将/home/yourusername/sumo替换为您实际的SUMO源代码绝对路径:
export PATH="$PATH:/home/yourusername/sumo/build/bin"
export SUMO_HOME="/home/yourusername/sumo"
保存文件后,运行以下命令使配置立即生效:
source ~/.bashrc
现在,您可以在终端任何位置直接输入sumo或sumo-gui来启动软件了。即使重启计算机,这个设置也会自动加载。
总结
本节课中,我们一起学习了在Ubuntu系统中从源代码编译安装SUMO 1.2.0的完整流程。我们首先安装了所有必要的依赖包,然后从GitHub克隆了源代码,接着设置了SUMO_HOME环境变量,并通过CMake和Make工具完成了编译。最后,我们将SUMO的可执行文件路径添加到系统PATH中,实现了全局调用。

SUMO是一款功能强大的交通模拟软件,广泛用于城市交通建模、公共交通调度等领域。在接下来的课程中,我们将探索如何将SUMO生成的交通数据(如车辆、行人轨迹)导入到NS3网络模拟器中,从而研究车联网等场景下的网络性能。
17:NS3中的Wireshark与PCAP分析 🕵️♂️


在本节课中,我们将学习如何在NS3网络模拟环境中使用Wireshark工具来分析PCAP数据包捕获文件。我们将了解Wireshark的基本操作,并学习如何用它来检查和分析由NS3模拟生成的网络流量。
Wireshark简介与实时捕获



Wireshark是一款功能强大的网络协议分析工具。它能够分析数据包捕获文件。

为了让Wireshark监听网络接口,我们需要以管理员权限运行它。在之前的版本中,可能只显示少数几个接口,但现在它可以列出所有可用的网络接口,例如Wi-Fi、环回接口、蓝牙等。
当系统通过Wi-Fi连接互联网并分配了IP地址时,Wireshark会捕获流经的各种数据包。例如,我们可能会看到来自IP地址192.168.x.x的广播数据包,这可能是一个连接到网络的路由器或设备在发送信息。
双击一个接口(如wlP3s0)可以开始实时数据包捕获。捕获到的数据包会显示详细信息,例如帧结构、接口名称、封装类型和时间戳。


以一个以太网帧为例:
- 目标地址:可能是广播地址
ff:ff:ff:ff:ff:ff。 - 源地址:设备的MAC地址。
- 协议:例如ARP(地址解析协议),其以太网类型字段为
0x0806。
在ARP请求中,我们可以看到发送方(源)的IP和MAC地址,以及目标IP地址。通过这种方式,我们可以分析网络中的通信。


Wireshark的统计与过滤功能
Wireshark的功能远不止于此。它提供了强大的统计和过滤工具。
首先,我们可以查看IO图表。在模拟初期,如果没有使用互联网,图表可能显示没有数据包被消耗。但当开始使用网络(如下载、上传)时,IO图表会动态变化,显示上传和下载的数据包速率。

IO图表可以显示每秒数据包数、比特数或字节数。它还能展示TCP错误等统计信息。我们可以自定义图表,添加不同的显示过滤器。
例如,我们可以使用一个过滤器来只显示特定协议(如SSH)的流量。当我们通过SSH协议(使用命令如 ssh -X user@server_ip)登录到远程服务器时,Wireshark可以捕获到相关的数据包。



在过滤后的视图中,我们可以看到SSH连接的建立过程,包括协议版本、密钥交换(如Diffie-Hellman)以及后续的加密数据包。
一个重要的安全提示:对于加密协议如SSH,其数据包内容是加密的,即使捕获到也无法直接读取密码等敏感信息。然而,对于非加密协议如Telnet,所有传输的数据(包括用户名和密码)都是以明文形式发送的,可以在Wireshark的TCP流跟踪中直接看到。因此,在企业网络中,管理员可能会在网关运行类似工具来监控网络活动,检查是否存在不安全的明文传输。

在NS3中生成并分析PCAP文件
上一节我们了解了真实环境中的Wireshark分析,本节我们来看看如何在NS3模拟中生成和分析PCAP文件。
在NS3脚本中,我们需要启用PCAP跟踪来捕获数据包。以下是一个示例代码片段,展示了如何为不同的网络设备(如点对点、Wi-Fi、CSMA)启用PCAP记录:
// 启用点对点设备的PCAP
pointToPoint.EnablePcapAll("third");
// 启用Wi-Fi设备的PCAP
wifiPhy.EnablePcap("wifi", wifiDevices);
// 启用CSMA设备的PCAP
csma.EnablePcap("csma", csmaDevices);
运行模拟脚本后,会生成对应的.pcap文件。例如,在一个有50个节点的Wi-Fi模拟中,可能会为每个节点生成一个独立的PCAP文件,总共50个文件。
我们可以用Wireshark打开任意一个文件进行分析。例如,打开节点11的捕获文件(wifi-11-0.pcap)。
在Wireshark中,我们可以看到:
- 数据包列表:显示了所有捕获到的帧,包括协议类型、源/目的地址、长度等信息。
- 协议详情:选择一个数据包,可以层层展开查看其各层协议的详细信息,例如:
- IEEE 802.11:无线帧的详细信息。
- 逻辑链路控制(LLC)。
- IP:版本、头长度、源/目的IP地址。
- UDP:源/目的端口号(例如从
49153到9)。 - 路由协议:如AODV协议的路由请求(RREQ)、路由回复(RREP)、路由错误(RERR)报文。
通过分析这些数据包,我们可以深入了解无线自组织网络(如AODV)的工作机制:
- Hello报文:新节点加入网络时广播,宣告自身存在。
- 路由请求(RREQ):节点需要发送数据但不知道路径时,广播RREQ。
- 路由回复(RREP):知道路径的节点单播回复RREP给请求者。
- 路由错误(RERR):当路径失效时,相关节点发送RERR。




比较不同路由协议的流量特征
我们可以利用Wireshark的IO图表功能,比较NS3中不同无线路由协议(如AODV、OLSR、DSR)的流量模式,这是一个很好的研究项目起点。
以下是分析步骤:
- 使用相同的节点数量和移动模型,分别运行配置了AODV、OLSR和DSR协议的NS3模拟。
- 为每个模拟生成PCAP文件(例如,都分析节点11的流量)。
- 在Wireshark中分别打开这些PCAP文件,并查看其IO图表。
- 观察和比较图表中显示的每秒数据包数和每秒比特数。
通过比较,我们可能会发现:
- AODV:在节点空闲时(模拟开始后的前50秒,尚未开始应用层通信),仍然有一定的基础控制流量来维护路由。
- OLSR:可能表现出不同的流量模式,在空闲时段消耗的带宽可能与AODV不同。
- DSR:又会有其独特的流量特征。
这种对比分析可以帮助我们理解不同路由协议的开销和性能特点。例如,可以观察哪个协议在空闲状态下的控制开销更小,哪个协议在建立路由时产生的流量更多。通过改变模拟参数(如节点数量、移动速度),可以进行更深入的研究。
课程总结
在本节课中,我们一起学习了如何在NS3网络模拟中使用Wireshark进行数据包分析。

我们首先介绍了Wireshark的基本操作,包括实时捕获和文件分析。然后,我们详细讲解了如何在NS3脚本中启用PCAP跟踪来生成数据包捕获文件。通过分析生成的PCAP文件,我们深入观察了网络协议(特别是AODV路由协议)的报文交互细节。最后,我们探讨了如何利用Wireshark的统计图表功能,对比不同路由协议的流量特征,这为进行网络协议性能评估和小型研究项目提供了实用的方法。




掌握这些技能,你将能够更有效地诊断NS3模拟中的网络问题,并定量分析不同网络配置和协议的行为。
18:GPSR协议在ns3中的安装与运行 🚗
在本节课中,我们将学习如何在网络模拟器3(ns-3)中安装和运行GPSR协议。GPSR是一种主要用于车载自组织网络的无状态路由协议。
概述
GPSR协议全称为贪婪周边无状态路由协议。它主要包含三个版本:GPSR、MM-GPSR和P-GPSR。本科生和研究生可以直接使用这些模块,而博士生或研究人员则可以对其进行修改。本节课将重点介绍该协议的安装过程。
安装准备


首先,我们需要确保系统满足安装ns-3的先决条件。以下是需要安装的软件包列表:


sudo apt-get install gcc g++ python python3sudo apt-get install gcc g++ python python3 python3-devsudo apt-get install mercurial python3-setuptools gitsudo apt-get install qt5-default mercurialsudo apt-get install gir1.2-goocanvas-2.0 python-gi python-gi-cairo python-pygraphviz python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython ipython3sudo apt-get install openmpi-bin openmpi-common openmpi-doc libopenmpi-devsudo apt-get install autoconf cvs bzr unrarsudo apt-get install gdb valgrindsudo apt-get install uncrustifysudo apt-get install doxygen graphviz imagemagicksudo apt-get install texlive texlive-extra-utils texlive-latex-extra texlive-font-utils dvipng latexmksudo apt-get install python3-sphinx diasudo apt-get install gsl-bin libgsl-dev libgsl23 libgslcblas0sudo apt-get install tcpdumpsudo apt-get install sqlite sqlite3 libsqlite3-devsudo apt-get install libxml2 libxml2-devsudo apt-get install cmake libc6-dev libc6-dev-i386 libclang-dev llvm-dev automakesudo apt-get install python-pipsudo pip install cxxfiltsudo apt-get install libgtk2.0-0 libgtk2.0-devsudo apt-get install vtun lxcsudo apt-get install libboost-signals-dev libboost-filesystem-dev
你可以复制以上命令并在终端中执行,以安装所有必需的依赖项。安装过程可能需要一些时间,具体取决于你的网络速度和系统性能。

下载并安装ns-3
完成环境准备后,接下来我们需要下载并安装特定版本的ns-3。本教程推荐使用ns-3.23版本。你可以使用wget命令下载压缩包:



wget https://www.nsnam.org/releases/ns-allinone-3.23.tar.bz2



下载完成后,使用以下命令解压文件:


tar xjvf ns-allinone-3.23.tar.bz2


解压后,你会得到一个名为ns-allinone-3.23的文件夹。进入该文件夹:

cd ns-allinone-3.23/ns-3.23
下载并集成GPSR模块
现在,我们需要将GPSR协议的源代码集成到ns-3中。使用git命令从GitHub仓库克隆GPSR模块:
git clone https://github.com/mohittahiliani/PhD-GPSR.git
克隆完成后,PhD-GPSR文件夹内会包含examples、figures、results、scripts和src等子目录。我们需要将这些内容复制到ns-3的对应目录中。
以下是需要执行的文件复制操作:

- 将
src/目录下的所有文件夹复制到ns-3.23/src/目录中。 - 将
examples/目录下的文件复制到ns-3.23/scratch/目录中。 - 将
figures/、results/、matlab/、scripts/等目录复制到ns-3.23/根目录下。

你可以通过图形界面手动复制粘贴,也可以使用终端命令完成。确保所有文件都放置在了正确的位置。


编译ns-3与GPSR模块
文件复制完成后,就可以开始编译整个ns-3项目了。在ns-3.23目录下,运行以下配置和编译命令:

./waf configure --enable-examples --enable-tests CXXFLAGS="-std=c++11"
./waf build
编译过程可能需要15到20分钟,具体时间取决于你的电脑性能。编译完成后,终端会显示已成功构建的模块列表,其中应包含GPSR、MM-GPSR和P-GPSR。



运行GPSR示例
编译成功后,我们可以运行一个GPSR示例来测试安装是否成功。进入ns-3.23目录,执行以下命令:
./waf --run scratch/gpsr-example


该命令会启动一个模拟场景。模拟过程可能需要一段时间(例如200秒),期间终端会输出模拟进度。模拟完成后,你可以在results/目录下查看生成的性能数据文件,例如分组投递率和平均跳数等指标。

总结

本节课我们一起学习了如何在ns-3.23环境中安装和配置GPSR路由协议模块。我们完成了从安装依赖、下载ns-3、集成GPSR源代码到编译和运行示例的完整流程。在下一节课中,我们将深入分析GPSR协议的源代码,并学习如何绘制和分析其性能特征图。
19:动态源路由 (DSR) 协议 🛣️
在本节课中,我们将学习一种名为动态源路由(Dynamic Source Routing,简称DSR)的网络路由协议。DSR是一种用于多跳无线网络的自组织、按需式路由协议。
协议概述
上一节我们介绍了路由协议的基本概念,本节中我们来看看DSR的具体工作机制。DSR协议主要具备以下特点:
- 它是自组织的。
- 它是一种反应式路由协议。这意味着只有在需要建立路由时,才会根据附近节点的情况来选择路径。
- 它适用于多跳网络。
DSR协议通过两种主要机制来运作:路由发现和路由维护。路由发现负责计算路径,而路由维护则负责处理链路故障,确保路由畅通。
DSR 工作原理示例


为了理解DSR如何工作,我们通过一个具体的网络场景来说明。
假设我们有一个网络,包含节点0、1、2、3、4、5、6、7、8、9。现在,节点0(源节点S)需要发送数据到节点6(目的节点D)。

初始时,源节点0并不知道到达节点6的路径。因此,它将发起路由发现过程。
路由发现过程
源节点0会向其所有的邻居节点(即节点2、4、8)广播一个特殊的数据包,称为路由请求包。
每个路由请求包包含以下核心信息:
- 唯一标识符 (ID):例如
5,用于区分不同的路由发现过程。 - 源节点地址:
0 - 目的节点地址:
6
所以,节点2、4、8收到的初始路由请求包可以表示为:
数据包 = (ID:5, 源:0, 目的:6)
当节点2收到这个包后,它会检查目的地是否是自身(节点6)。如果不是,它会在数据包中追加自己的地址,然后继续向它的邻居节点(节点3和节点5)广播这个更新后的包。
因此,从节点2发往节点3的包变为:
数据包 = (ID:5, 路径:[0, 2], 目的:6)
同理,节点4收到包后,会追加自己的地址,并向其邻居节点(节点5和节点8)广播:
数据包 = (ID:5, 路径:[0, 4], 目的:6)
这个过程在所有中间节点中继续。每个节点在转发路由请求包时,都会遵循以下规则:
- 检查包的唯一ID和源/目的地址。
- 如果本节点就是目的节点,则路由发现成功。
- 否则,将自己的地址加入路径列表,并继续广播。
- 如果一个节点收到了相同ID的路由请求包,它会丢弃后续收到的副本,以避免广播风暴和循环。

最终,目的节点6会通过不同的路径收到多个路由请求包。假设它收到了以下三条路径的请求:
- 路径 1:
0 -> 2 -> 3 -> 6 - 路径 2:
0 -> 4 -> 5 -> 6 - 路径 3:
0 -> 2 -> 3 -> 7 -> 6



路由缓存与选择
目的节点6在收到这些路由请求后,会通过单播的方式,沿原路径反向发送一个路由回复包给源节点0。源节点0因此会获知到达节点6的多条可用路径。
DSR协议的一个关键特性是路由缓存。源节点和中间节点都会将已知的路由信息存储在本地的缓存中。
// 概念上的路由缓存示例
路由缓存 = {
“目标节点6”: [路径1, 路径2, 路径3],
“目标节点X”: [...],
...
}


当源节点0需要发送数据时,它会首先检查缓存中是否有到节点6的可用路由。如果有,它可以直接使用,而无需再次发起耗能的路由发现过程。数据包的头部会携带完整的源路由路径,例如 [0, 4, 5, 6],指导数据包如何被逐跳转发。

路由维护

如果某条链路在通信过程中失效(例如,节点4和5之间的连接断开),检测到链路故障的节点(如节点4)会向源节点0发送一个路由错误包。
源节点0收到错误包后,会将缓存中所有包含该失效链路的路径标记为无效或删除。之后,它可以从缓存中选择另一条备用路径(如路径 0 -> 2 -> 3 -> 6)来继续通信。




只有当缓存中的所有路由都失效时,源节点才需要重新发起路由发现过程。

if (缓存中存在到目的地的有效路由) {
使用缓存中的路由发送数据;
} else {
发起新的路由发现过程;
}
总结
本节课中我们一起学习了动态源路由协议。DSR是一种高效的反应式路由协议,它通过路由发现机制按需寻找路径,并通过路由维护机制处理网络变化。其核心优势在于利用路由缓存来减少路由发现的开销,并支持多路径。然而,维护缓存和携带完整源路由信息也增加了协议的复杂性和数据包开销。




20:无线自组织网络
概述

在本节课中,我们将学习无线自组织网络。我们将了解其定义、不同的路由协议分类、反应式与主动式路由协议的区别,并对AODV和DSDV协议进行性能比较和简单的模拟结果分析。
什么是无线自组织网络?🤔

无线自组织网络是由无线移动节点动态形成的临时网络集合,无需使用任何现有的网络基础设施或集中式管理。
这意味着此类网络是无基础设施的。一个很好的例子是:你有一台笔记本电脑,其他几台笔记本电脑也带有Wi-Fi驱动。仅使用这几台笔记本电脑,无需任何接入点或路由器,它们就能形成一个网络。这就是我们所说的自组织网络。如何形成这种网络以及路由协议背后的挑战,正是无线自组织网络的核心。

这种无处不在的计算类型通常被称为普及或隐形计算。这种网络无处不在。一个现代的例子是使用手机热点。你可以使用Wi-Fi设备共享热点,这种热点网络也属于无线自组织网络的范畴。
自组织网络的特性 📡
自组织网络具有以下特性:
- 自主协作:设备需要在没有用户干预的情况下自主协作。网络中的所有节点都将自主运行。
- 快速自组织:如果特定节点出现故障,它们会自动形成替代路径或另一个网络。
- 独立于基础设施:如前所述,不需要接入点。没有接入点时,所有节点自行组成网络。
- 异构性与自适应性:节点可能来自不同制造商,具有不同的能量水平、介质访问控制协议,但它们仍然可以相互通信,并能适应网络行为的变化。

自组织网络面临的挑战 ⚠️
自组织网络设计面临多项挑战:

- 安全性:无论是信息安全还是网络安全,都是一个重大挑战。
- 可扩展性:随着网络中节点数量的增加,如何处理可扩展性问题。
- 负载均衡:主机之间的连接如何交换数据包。
- 信任机制:每个节点都有一个信任值。信任值高的节点会转发数据包,信任值低的则不会。
- 服务质量:无线网络通常服务质量较低,如何确保QoS是一大挑战。
- 资源开销:通常设备的CPU和内存资源有限。
- 电池寿命影响:设备电池能维持多久是至关重要的问题。
协议设计要点 🛠️
设计路由协议时必须考虑以下几点:

- 分布式运行:整个网络是分布式的,协议必须在分布式环境中运行。
- 无环路路由:源节点和目的节点之间的路径不应形成环路,数据包不应在环路中循环。
- 支持多路径:协议应能计算多条路由。
- 快速建立路由:协议应能快速找到有效路由。
- 最小化开销:在拓扑变化时,其通信开销应尽可能小。
主要路由协议分类 📊

本课程主要考虑以下四种协议:AODV、DSR、DSDV 和 OLSR。我们将对这四种协议进行比较。

路由协议可以根据不同方式分类:
- 对拓扑变化的反应方式:主动式路由协议与反应式路由协议。
- 网络架构:平面架构与分层架构。
- 驱动方式:基于表驱动、按需驱动或关联性驱动。
例如,DSDV是基于表驱动的,而AODV和DSR是基于按需驱动的。

路由协议分类详解

在分类中,主动式路由协议 包括OLSR和DSDV;反应式路由协议 包括DSR和AODV。接下来几周,我们将重点评估这四种协议。
主动式路由协议 🔄
主动式路由协议通常是表驱动的。这意味着数据包的转发基于预先计算好的路由表。
- 路由预先计算:在数据包需要转发之前,路由已经根据各种参数计算好并填入路由表。
- 维护开销高:由于需要维护和定期更新所有节点的路由表(例如当节点失效时),会产生较高的开销。
- 延迟较低:因为路由始终处于维护状态,所以数据转发延迟较低。
反应式路由协议 ⚡
反应式路由协议通常是按需驱动的。这意味着只有在有数据传输需求时才会计算路由。
- 按需计算路由:仅在需要发送数据时才确定路径。
- 延迟较高:由于需要临时计算路由,初始延迟较高。
- 开销较低:因为只在需要时才维护路由,所以开销相对较低。

协议对比:AODV 与 DSDV

理解了主动式和反应式的区别后,我们可以更好地比较AODV和DSDV。DSDV是目标序列距离矢量算法,属于主动式路由。AODV是按需距离矢量路由算法,属于反应式路由。
此外,我们还有动态源路由协议和最优链路状态路由协议。我们将一起评估这四种协议的性能。
AODV 协议工作原理

AODV完全是按需的、反应式的。在需要之前不会确定路由。每个节点都包含一个路由表,记录如何到达其他节点的下一跳信息。
路由发现过程:
- 当源节点需要向目的节点发送数据但无可用路由时,会发起路由发现。
- 源节点广播一个路由请求 数据包。
- 邻居节点收到RREQ后,继续广播,直到到达目的节点。
- 目的节点或中间节点(如果有到目的节点的有效路由)会沿着反向路径单播一个路由应答 数据包回源节点。
- 源节点收到RREP后,便建立了到目的节点的路由。
RREQ使用广播,而RREP使用单播。路由选择通常基于最短路径或特定服务质量参数。

DSDV 协议工作原理
DSDV是一种主动式路由协议,全称是目标序列距离矢量。它基于距离矢量算法,主要特点是避免路由环路。
- 维护路由表:每个节点维护一个到达所有目的地的路由表,包含所需跳数。
- 序列号:使用序列号来区分新旧路由,避免环路。序列号随更新递增。
- 定期更新:路由更新会定期广播给所有节点,以保持路由表的一致性。当节点失效时,更新信息会传播开来,但更新过程需要时间。
路由选择:广播更新包含目的地地址、跳数、序列号。优先使用序列号最高的路由;如果序列号相同,则使用跳数最少的路由。
性能比较 📈
我们将使用NS3详细进行性能比较。这里先概述一些性能特征。比较通常在10到100个节点的规模下进行,评估指标包括:

- 分组投递率
- 平均吞吐量
- 端到端延迟
- 路由开销
以下是AODV与DSDV的简要比较结果(假设图中红色代表AODV,绿色代表DSDV):

- 分组投递率:AODV的PDR通常高于DSDV。高PDR意味着更高的网络可靠性。
PDR = (接收的数据包数 / 发送的数据包数)
- 平均吞吐量:AODV的吞吐量(比特/秒)在多数情况下也优于DSDV,尽管在某些节点数量下可能存在波动。
- 端到端延迟:AODV的平均延迟显著低于DSDV。延迟应尽可能小。
- 路由开销:AODV的路由开销与PDR表现类似,在某些情况下可能略优于DSDV,但差异可能不大。路由开销指发送和接收数据包所产生的额外开销。
总结


本节课我们一起学习了无线自组织网络的基本概念、特性以及面临的主要挑战。我们深入探讨了路由协议的设计要点,并将协议分为主动式(如DSDV)和反应式(如AODV)两大类。通过分析AODV和DSDV的工作原理及性能比较,我们发现对于大多数应用场景,AODV在吞吐量、延迟和分组投递率方面通常优于DSDV。当然,DSDV在路由无环路、路由表稳定方面也有其优势,适用于节点能量充足、拓扑相对稳定的环境。在接下来的课程中,我们将使用NS3对所有四种协议进行更全面的性能评估。
21:NS3入门介绍 🚀

在本节课中,我们将学习网络模拟器3(NS3)的基本概念、核心抽象模型以及其工具集。我们将了解NS3是什么,它如何工作,以及如何利用它进行网络研究和教育。


概述


NS3是一个主要用于研究和教育目的的开源离散事件网络模拟器。它允许用户在部署真实网络设备前,通过模拟来测试和验证网络设计。与早期版本NS2不同,NS3是一个全新的模拟器,虽然部分模型从NS2移植而来,但它并非NS2的向后兼容版本。
NS3简介
NS3是一个离散事件模拟器。这意味着模拟过程由一系列离散的事件驱动,每个事件在特定的模拟时间点发生。这种模拟方式高效且精确。
NS3的设计目标是成为一套可组合的库,能够与其他外部软件库协同工作。它不是一个独立的软件,而是可以与多种第三方工具(如动画器和数据分析工具)集成。然而,使用NS3需要熟悉命令行操作,并具备C++或Python的软件开发基础。



注意:NS3主要在Linux系统上运行。虽然可以在macOS上配置(需要安装Xcode),但目前对Windows的官方支持仍在开发中,因此建议使用Linux系统以获得最佳体验。
NS3工具集 🛠️
以下是本课程中将学习使用的一些核心工具:
- Gnuplot:用于绘制网络性能特征图。
- Wireshark:用于捕获和分析网络数据包。
- NetAnim:网络动画工具,用于可视化模拟过程。
- Trace Metrics:用于处理NS3的ASCII跟踪文件。
- Flow Monitor:一个强大的工具,用于监控数据流,统计丢包率、传输速率、接收速率等。
- PyViz:另一个实时网络动画可视化工具。
此外,我们还会学习其他软件,如escapes、gcc等。

NS3的核心抽象模型 🧱
NS3通过提供完整的源代码,让用户能够深入理解、修改甚至从头开发网络协议。其整个库围绕五个核心抽象类构建:
1. 节点 (Node)

节点是NS3中的基本计算设备,可以将其理解为一台计算机。
- C++类名:
Node - 功能:节点可以像真实计算机一样,安装外围设备、应用程序、协议栈和驱动程序。
- 容器类:
NodeContainer,用于管理多个节点。
2. 应用程序 (Application)
应用程序运行在NS3节点上,用于驱动模拟世界中的网络行为。

- C++类名:
Application - 示例:
UdpEchoClientApplication(UDP回声客户端应用)UdpEchoServerApplication(UDP回声服务器应用)
- 作用:例如,一个节点运行回声服务器,另一个节点运行回声客户端,两者之间可以模拟网络通信。
3. 信道 (Channel)
信道代表了节点之间的通信媒介或路径。
- C++类名:
Channel - 类型:
- 点对点信道 (PointToPointChannel):直接连接两个节点。
- CSMA信道 (CsmaChannel):模拟基于总线(如以太网)的多节点共享信道。
- Wi-Fi信道 (WifiChannel):模拟无线通信媒介。
- 作用:定义了数据在节点之间传输的物理或逻辑媒介。

4. 网络设备 (NetDevice)
网络设备是软件驱动和模拟硬件的结合体,相当于计算机中的网卡(硬件)及其驱动程序(软件)。
- C++类名:
NetDevice - 功能:网络设备安装在节点上,使节点能够通过信道与其他节点通信。它是节点与信道之间的接口。

5. 拓扑助手 (Topology Helpers)


在大型模拟网络中,手动配置众多节点、设备和信道之间的连接非常繁琐。拓扑助手类提供了便捷的方法来快速构建复杂的网络拓扑。
- 作用:帮助用户自动化和简化网络拓扑的创建过程,例如决定数据包从源节点到目的节点的最佳或备用路径。
NS3模型与构建系统

NS3内置了大量现成的网络模型,用户无需从头实现即可直接使用。
- 设备模型:网桥、路由器、频谱设备等。
- 协议模型:AODV、DSDV、OLSR等路由协议,以及OpenFlow等。
- 支持工具:核心模块支持回调、事件调度、日志记录等。
如何构建NS3应用

NS3使用一个名为waf的Python构建框架。
- 配置:在NS3根目录下运行
./waf configure,检查并配置编译环境。 - 编译:运行
./waf build来编译整个NS3系统或特定的模块。 - 运行示例:编译成功后,可以运行示例程序,例如
./waf --run hello-simulator。
典型的开发流程是在Linux环境下,进入NS3的工作目录(例如 ~/ns-allinone-3.27/ns-3.27),使用上述waf命令进行操作。

总结
本节课我们一起学习了网络模拟器3(NS3)的基础知识。我们了解到NS3是一个开源的离散事件模拟器,其核心是五个抽象概念:节点、应用程序、信道、网络设备和拓扑助手。这些抽象帮助我们以编程方式构建和模拟复杂的网络。同时,我们还简要介绍了NS3丰富的工具集和基于waf的构建系统。

建议学习者动手安装NS3(或使用提供的虚拟机镜像),并尝试运行第一个示例,为后续的实践操作打下基础。在接下来的课程中,我们将通过具体示例深入NS3的模拟世界。
22:网络性能指标 🚀


在本节课中,我们将学习网络性能指标。这些指标是评估任何网络(无论是有线还是无线)性能的关键工具。我们将讨论其背后的理论概念,并在本周后续课程中基于这些指标进行大量实例分析。请仔细观看所有视频,以便更好地理解网络性能背后的各项指标。

我们将要学习的指标包括:吞吐量、端到端延迟、响应时间与延迟、丢包与分组丢失、分组投递率以及抖动。
吞吐量 📈
上一节我们介绍了本课程的目标,本节中我们来看看第一个核心性能指标:吞吐量。

吞吐量是指在单位时间内通过网络成功传输的数据量。具体来说,它衡量的是在给定时间内,网络中两个不同计算机或节点之间发送的数据量。吞吐量通常以比特每秒(bps)为单位进行测量。小写“b”代表比特,大写“B”代表字节。吞吐量指的是有效传输速率,即数据包在网络中成功传输的速率。
与吞吐量相关的另一个概念是“有效吞吐量”。有效吞吐量指的是对接收应用程序有用的数据量,有时也称为应用层吞吐量。两者的区别在于,吞吐量可能包含网络各层(如网络层、传输层)的所有数据包,而有效吞吐量主要关注应用层的有用数据。
吞吐量还可以分为瞬时吞吐量和平均吞吐量。
吞吐量计算示例
以下是理解吞吐量计算的一个简单示例:

假设有两个有线节点:节点0和节点1。它们之间有一条物理链路,我们通常用两个参数来描述这条链路:数据速率(例如 5 Mbps)和延迟(例如 2 ms)。数据速率(或称带宽)表示链路的最大传输能力,延迟表示数据包在该链路上传输所需的时间。
如果节点0是源节点,节点1是目的节点,节点0生成数据包并发送给节点1。数据包以链路的最大速度(5 Mbps)传输,并经历2ms的延迟。到达节点1的数据包数量与时间的比率,就是节点0到节点1的瞬时吞吐量。
现在,假设节点0还要向另一个节点(节点2)发送数据。节点0到节点2的路径可能经过节点1,形成一条多跳路径。在这种情况下,我们可以计算节点0到节点1(T1)和节点1到节点2(T2)的瞬时吞吐量。那么,从节点0到节点2的平均吞吐量可以近似为 (T1 + T2) / 2。
吞吐量是衡量任何网络性能的基础且至关重要的指标。它主要受到延迟、网络拥塞以及缺乏拥塞控制等因素的影响。
端到端延迟 ⏱️
上一节我们介绍了吞吐量,本节中我们来看看另一个关键指标:端到端延迟。
端到端延迟是指数据包从源节点传输到目的节点所经历的总时间。它是路径上所有链路和中间节点延迟的总和。延迟通常由两部分构成:传输延迟和传播延迟。
- 传输延迟:指在链路上发送数据包所需的时间。如果发送 B 比特的数据,链路数据速率为 R bps,则传输延迟为 B / R。
- 传播延迟:指信号在物理介质中传播所需的时间。它取决于链路的长度(例如电缆长度)以及信号在介质中的传播速度(例如光速)。
端到端延迟计算示例

考虑一个从源节点 S 到目的节点 D 的网络路径,中间经过节点1、2、4。假设链路特性如下:
- S 到 1:有线连接,数据速率 10 Mbps,延迟 2 ms。
- 1 到 2:无线连接,延迟可变(受无线环境因素影响)。
- 2 到 4:有线连接,数据速率 1 Mbps,延迟 1 ms(低速链路)。
- 4 到 D:有线连接,数据速率 100 Mbps,延迟 1 ms(高速链路,可能连接互联网网关)。
那么,从 S 到 D 的端到端延迟就是这四条链路延迟之和:延迟(S->D) = 延迟(S->1) + 延迟(1->2) + 延迟(2->4) + 延迟(4->D)。
需要注意的是,如果节点是移动的(例如无线网络中的节点1和2),由于移动性,延迟可能会增加。端到端延迟是衡量网络响应速度的重要指标。
响应时间与延迟 🔄
接下来我们探讨响应时间和延迟,这两个术语在网络环境中经常互换使用。

在网络中,延迟 衡量的是数据从源到达目的地所需的时间。它通常以往返时间(RTT)来度量。RTT 是指从发送数据包到接收到该数据包的确认(或回应)所经过的总时间。
一个常见的例子是使用 ping 命令。当你在终端输入 ping www.google.com 时,你的计算机会向 Google 服务器发送一个探测包,服务器会回应。命令输出的时间(例如 “time=5ms”)就是该次探测的 RTT,它反映了你到 Google 服务器的网络延迟。
较低的延迟值意味着网络连接质量较好。高延迟会影响用户体验,尤其是在实时应用(如在线游戏、视频通话)中。网络拥塞是导致高延迟的主要原因之一。

延迟计算
延迟(通常指RTT)可以简单表示为:
RTT = T_transmit + T_propagate + T_process + T_return
其中 T_transmit 和 T_propagate 是往返路径上的传输和传播时间,T_process 是目的地的处理时间,T_return 是返回路径的时间。在简化模型中,我们常关注总时间。
分组丢失与丢包 📉
网络性能的另一个重要方面是数据包的可靠性,即分组丢失与丢包。这两者有所区别。
- 分组丢失:指数据包在网络传输过程中未能到达目的地。这可能由于链路拥塞、无线电频率干扰(无线网络)、信号衰减或物理链路故障等原因造成。
- 丢包:通常指数据包到达了目的节点,但由于某种原因被该节点主动丢弃。常见原因包括:
- 队列溢出:每个网络接口都有一个缓存队列(FIFO)。如果队列已满,新到达的数据包无处存放,就会被丢弃。
- 恶意节点:网络中可能存在恶意节点,其目的就是丢弃经过它的所有或部分数据包。
示例说明
假设节点0向节点1发送数据包。
- 分组丢失场景:数据包在传输路径上(例如由于严重的无线干扰)被损坏或完全丢失,根本未能到达节点1。
- 丢包场景:数据包成功到达节点1的网络接口,但此时节点1的接收队列已满,因此尽管数据包“到了门口”,还是被丢弃了。
理解分组丢失和丢包的原因对于诊断和优化网络至关重要。
分组投递率 ✅
分组投递率是衡量网络可靠性的一个直接指标。

分组投递率是指成功接收的数据包数量与发送的数据包总数之比。其公式为:
PDR = (Σ 接收的数据包数量) / (Σ 发送的数据包数量)
一个高性能的网络追求尽可能高的 PDR 值,理想情况下接近 1(或 100%)。PDR 越高,表明网络传输数据越可靠。

抖动 📶
最后,我们讨论抖动,这是实时通信(如网络电话、视频会议)中的一个关键指标。
抖动 是指数据包到达时间间隔的变化。在稳定的网络中,数据包应以均匀的间隔到达。然而,由于网络拥塞、路由变化或排队延迟,数据包的到达时间会产生波动,这种波动就是抖动。
抖动对语音 over IP(VoIP)和流媒体等实时应用尤其有害。高抖动会导致语音断断续续、视频卡顿。
- 典型值:通常,抖动量应低于 40 毫秒才能保证良好的语音质量。
- 产生原因:网络拥塞、无线网络干扰、服务质量(QoS)配置不当或硬件性能不佳都可能导致高抖动。
- 缓解方法:
- 升级网络硬件(如路由器)。
- 提高互联网连接带宽和质量。
- 使用抖动缓冲区。这是一个在接收端设置的缓存区,它会暂存到达的数据包,然后以恒定速率播放出来,从而平滑因抖动带来的不均衡,但会引入额外的延迟。
总结 🎯
本节课中,我们一起学习了评估网络性能的核心指标:
- 吞吐量:单位时间内成功传输的数据量,是网络能力的根本体现。
- 端到端延迟:数据包从源到目的的总时间,影响网络响应速度。
- 延迟(RTT):数据包往返所需时间,是衡量网络“延迟”的常用方式。
- 分组丢失与丢包:区分了数据包未能到达和被丢弃的不同情况,关乎网络可靠性。
- 分组投递率:成功投递的数据包比例,是可靠性的量化指标。
- 抖动:数据包到达时间的变化,对实时应用质量至关重要。

理解并监控这些指标,是分析、诊断和优化任何有线或无线网络性能的基础。在接下来的课程中,我们将利用这些指标进行实际的网络模拟与分析。
23:NS3的外部工具 🛠️
在本节课中,我们将学习网络模拟器3(NS3)所使用的一系列第三方工具。这些工具对于分析和可视化模拟结果至关重要,其中一些工具将伴随你的整个职业生涯。

上一节我们介绍了NS3的基本架构,本节中我们来看看这些强大的辅助工具。
Wireshark 数据包分析器

Wireshark是一个网络数据包分析器或数据包追踪器。它可以分析各种网络数据包。如果你想设计自己的协议和自定义数据包结构,Wireshark也能进行分析。例如,它可以处理TCP、UDP、SNMP等多种协议。

网络数据包分析器会捕获网络数据包,并尽可能详细地显示数据包信息,甚至可以达到比特级别的细节。NS3之所以包含Wireshark,是因为它能够处理一种名为“数据包捕获”的文件,通常简称为Pcap文件。

以下是Wireshark的主要功能列表:
- 它可以创建各种统计信息。
- 它可以根据多种条件为数据包着色。
- 它可以根据多种条件搜索数据包。
- 它可以根据多种条件过滤数据包。
- 它可以导出数据。
- 它可以保存、显示和导入数据包。
Wireshark适用于Linux、Mac和Windows等所有主流操作系统。在Ubuntu Linux上,你可以使用以下命令安装:
sudo apt install wireshark
在Fedora上,你可以使用:
sudo dnf install wireshark
默认情况下,只有超级用户(root)才能访问所有网络接口。为了让普通用户也能使用Wireshark监控接口,需要进行额外配置。


NetAnim 网络动画器
NetAnim是网络动画器的缩写。它是一个用于可视化NS3模拟过程的工具。
不建议直接通过Linux系统包管理器安装NetAnim,因为这可能与NS3生成的XML动画文件不兼容。正确的安装方法如下,每一行对应一个终端命令:
sudo apt-get update
sudo apt-get install qt4-dev-tools
安装完成后,在NS3的netanim-3.10x目录下,运行./netanim命令来启动动画器。

要在源代码中启用NetAnim,需要进行以下配置。首先,在头文件部分包含:
#include "ns3/netanim-module.h"
然后,在Simulator::Run()函数之前,添加如下代码来设置动画接口和节点位置:
AnimationInterface anim ("animation.xml");
anim.SetConstantPosition (node, x, y);
这段代码会生成一个XML文件,该文件可以在NetAnim窗口中打开并播放动画。
Trace-Matrix 追踪矩阵分析器

Trace-Matrix是一个第三方追踪矩阵分析软件。你可以从tracematrix.net或SourceForge网站下载其最新版本。
在Windows系统中,可以直接双击JAR文件运行。在Linux或Mac系统中,需要在终端使用以下命令运行:
java -jar tracematrix.jar
该软件处理的是NS3生成的.tr格式的追踪文件,这种文件包含ASCII格式的追踪数据。

要在代码中启用ASCII追踪,需要在Simulator::Run()函数之前添加代码。例如,为CSMA和Wi-Fi助手类启用追踪:
AsciiTraceHelper ascii;
csma.EnableAsciiAll (ascii.CreateFileStream ("csma.tr"));
phy.EnableAsciiAll (ascii.CreateFileStream ("wifi.tr"));
运行模拟后,会生成csma.tr和wifi.tr两个文件,你可以用Trace-Matrix分别打开它们进行分析。

数据包捕获 (PCAP) 与 TCPdump
数据包捕获功能可以生成PCAP文件,这些文件可以用Wireshark或TCPdump进行分析。
在代码中启用PCAP捕获的方法与ASCII追踪类似,但针对的是点对点、Wi-Fi物理层和CSMA等助手类。例如:
pointToPoint.EnablePcapAll ("third");
phy.EnablePcapAll ("third");
csma.EnablePcapAll ("third");
这段代码会为每个网络接口生成独立的PCAP文件,文件名格式类似于third-0-0.pcap、third-0-1.pcap等。

TCPdump是一个命令行网络分析工具。你可以使用如下命令分析PCAP文件:
tcpdump -tt -r filed.pcap
这对于希望深入理解TCP/IP协议栈的网络管理员来说非常有用。

Flow Monitor 流监控器
Flow Monitor是NS3中一个非常强大的内置工具,能够提供详尽的流级别统计数据,例如数据包丢失、丢包、传输/接收能量以及收发数据包数量等。

要使用Flow Monitor,首先需要在源代码中包含头文件:
#include "ns3/flow-monitor-helper.h"
然后,在Simulator::Run()函数之前安装流监控器:
Ptr<FlowMonitor> flowMonitor;
FlowMonitorHelper flowHelper;
flowMonitor = flowHelper.InstallAll ();
模拟运行结束后,将统计数据写入XML文件:
flowMonitor->SerializeToXmlFile ("flow-monitor.xml", true, true);
分析这个XML文件,你可以获得关于协议、端口号、数据包流等丰富信息。

PyViz 可视化工具

PyViz是一个基于Python的可视化工具,但因其依赖包已从Ubuntu仓库移除,在较新系统中可能无法工作。它的功能与NetAnim类似,但更集成于NS3内部。
你可以通过以下两种方式之一在运行脚本时启动PyViz:
./waf --run scratch/first --vis
或
./waf --run scratch/first --visualizer
如果环境配置正确,这将打开一个图形化窗口,动态显示网络模拟过程。
Gnuplot 绘图工具
Gnuplot是一个功能强大、开源且专业的绘图软件,是值得终身学习的工具。绝大多数学术期刊出版物中的图表都使用Gnuplot生成。它支持Windows、Linux和Mac系统,完全免费。
以下是一个简单的Gnuplot脚本示例,用于生成PNG格式的图表:
set terminal png size 600,480
set output 'filed.png'
set title "Title of the graph"
plot "filed.dat" using 1:2 with linespoints title "Congestion"
这段脚本将数据文件filed.dat中的第一列作为X轴,第二列作为Y轴,绘制带有点的线图,并添加图例“Congestion”。你还可以在同一张图中绘制多条曲线,甚至直接绘制数学函数,例如:
plot x**2 + 2*x + 1
Gnuplot的强大之处在于,你可以将复杂的绘图指令写在一个脚本文件中,轻松生成大量高质量、可出版的图表。


本节课中我们一起学习了NS3的多种外部和内部工具。从用于深度数据包分析的Wireshark,到用于动态可视化的NetAnim和PyViz,再到用于数据分析的Trace-Matrix、Flow Monitor和Gnuplot,这些工具共同构成了NS3强大的后处理与分析生态系统。掌握这些工具,将极大地提升你设计、运行和分析网络模拟实验的能力。
24:OSI模型各层功能 🧱
在本节课中,我们将学习计算机网络的核心基础——OSI(开放系统互连)模型。我们将详细探讨其七个层次,了解每一层的具体功能以及数据在网络中传输时,各层是如何协同工作的。
概述
上一节我们介绍了计算机网络和拓扑结构的基础知识。本节中,我们将深入探讨OSI模型的七个层次。OSI模型是计算机网络、云计算、物联网等众多领域的基石。理解每一层的功能,对于掌握网络通信原理至关重要。
OSI模型简介
OSI模型由国际标准化组织(ISO)制定,旨在为不同系统之间的通信提供标准框架。该模型将网络通信过程划分为七个层次,每一层都有其特定的功能和协议。
当源节点向目标节点发送数据包时,数据会自上而下(从应用层到物理层)穿过每一层。每经过一层,该层就会为数据添加一个头部(有时在数据链路层还会添加尾部)。这个过程称为封装。在接收端,数据自下而上(从物理层到应用层)穿过各层,每一层会移除对应的头部和尾部,这个过程称为解封装。
下图展示了数据从设备A传输到设备B,经过中间节点时的封装与解封装过程:

OSI模型各层详解
接下来,我们逐一了解OSI模型的七个层次。
1. 物理层 (Physical Layer)
物理层是模型的最底层,负责在物理媒介上传输原始的比特流(0和1)。它定义了接口的物理特性、数据的电气表示、同步方式、传输模式(如单工、半双工、全双工)以及物理拓扑结构。
- 功能:在节点间移动比特。
- 数据单位:比特 (Bit)
- 协议/标准示例:
IEEE 802.3(以太网)IEEE 802.11(Wi-Fi)IEEE 802.15.1(蓝牙)
- 关键参数:数据速率(如150 Mbps)。
2. 数据链路层 (Data Link Layer)
数据链路层负责将物理层传来的比特流组织成帧,并在直接相连的两个节点之间进行无差错的传输。它管理物理寻址、流量控制、差错控制和介质访问。
- 功能:节点到节点的帧传递。
- 数据单位:帧 (Frame)
- 关键概念:
- 物理地址 (MAC地址):每个网络接口的唯一标识符,格式如
A0:3E:4F:23:59:32。 - 介质访问控制 (MAC):决定设备何时可以在共享介质上发送数据。
- 物理地址 (MAC地址):每个网络接口的唯一标识符,格式如
3. 网络层 (Network Layer)
网络层负责将数据包从源主机跨越多个网络路由到目的主机。它处理逻辑寻址(如IP地址)和路径选择(路由)。
- 功能:源到目的的数据包传递。
- 数据单位:数据包 (Packet)
- 关键概念:
- 逻辑地址 (IP地址):如
192.168.1.1或2001:db8::1。 - 路由 (Routing):为数据包选择最佳路径。
- 逻辑地址 (IP地址):如
- 协议示例:
IPv4,IPv6,ICMP,ARP。
4. 传输层 (Transport Layer)
传输层确保数据能够完整、有序地从发送方进程传递到接收方进程。它提供端到端的连接管理、流量控制、差错控制和数据分段/重组。
- 功能:进程到进程的完整消息传递。
- 数据单位:段 (Segment)
- 协议示例:
- TCP (传输控制协议):面向连接,提供可靠传输。
- UDP (用户数据报协议):无连接,提供高效但不可靠的传输。
- SCTP (流控制传输协议):用于多媒体流等新型应用。
5. 会话层 (Session Layer)
会话层负责建立、管理和终止两个通信主机之间的对话(会话)。它通过插入同步点来管理数据交换,以便在传输中断时能够从检查点恢复,而无需重传所有数据。
- 功能:建立、维护和同步通信会话。
6. 表示层 (Presentation Layer)
表示层处理两个系统之间交换信息的语法和语义问题,确保一个系统应用层发出的信息能被另一个系统的应用层读懂。它负责数据的转换、加密、解密、压缩和解压缩。
- 功能:数据格式转换、加密与压缩。
- 处理过程:在发送端,数据被编码、加密、压缩;在接收端,数据被解码、解密、解压缩。
7. 应用层 (Application Layer)
应用层是用户与网络的接口,包含了用户直接使用的各种网络服务和协议。我们日常使用的网络功能都基于这一层的协议。
- 功能:为应用程序提供网络服务接口。
- 协议示例:
HTTP/HTTPS:万维网数据通信。FTP:文件传输。SMTP/POP3/IMAP:电子邮件服务。DNS:域名解析。
协议与层次对应关系
下图清晰地展示了各层常见的协议分布:

值得注意的是,应用层、表示层和会话层的协议通常被紧密地绑定在一起实现。
总结
本节课我们一起学习了OSI模型的七个层次。我们了解到,数据从应用层产生,经过层层封装,最终变成物理链路上的比特流进行传输;接收端则反向解封装,将数据还原给目标应用。每一层都扮演着不可或缺的角色:
- 物理层处理比特。
- 数据链路层处理帧。
- 网络层处理数据包并负责路由。
- 传输层处理段并保证端到端可靠性。
- 会话层管理对话。
- 表示层转换数据格式。
- 应用层提供用户服务。


只有最上层的应用层协议是用户可见的,其下各层的工作对用户而言是透明的。掌握OSI模型是理解复杂网络技术的第一步。
25:第一步 🚀

在本节课中,我们将学习如何开始使用网络模拟器3(NS-3)。我们将了解其基本文件夹结构,并运行一个简单的示例程序来验证安装是否成功。

概述
网络模拟器3(NS-3)是一个用于网络研究和教育的离散事件模拟器。与图形界面工具不同,NS-3主要通过终端命令行进行操作。因此,熟悉Linux终端命令是使用NS-3的重要前提。在之前的课程中,我们已经学习了25个基本的Linux命令。本节我们将进入NS-3的目录,了解其结构,并运行第一个“Hello Simulator”程序。

进入工作目录
首先,我们需要进入NS-3的工作目录。所有NS-3的操作都将在 ns-allinone-3.27/ns-3.27 这个文件夹中进行。

cd ns-allinone-3.27/ns-3.27
符号说明:在后续教程中,
~/ns-allinone-3.27/ns-3.27将简写为ns-3.27,而~/ns-allinone-3.27将简写为ns-allinone-3.27。请理解这种简写方式。



核心文件夹结构


进入 ns-3.27 目录后,使用 ls 命令可以查看其包含的多个文件夹。每个文件夹都有其特定的用途。
以下是主要文件夹及其功能的介绍:

scratch/:这是执行文件夹。所有需要运行的示例程序或我们自己编写的代码,都需要复制到这个文件夹中才能执行。src/:这是源代码文件夹。NS-3所有模块的C++源代码都存放在这里。build/:这是编译文件夹。当我们编译NS-3或自己的程序时,生成的可执行文件和库文件会存放在这里。examples/:这是示例文件夹。NS-3官方提供了大量涵盖各种网络场景(如TCP、UDP、无线网络等)的示例程序,供我们学习和参考。

验证安装与运行第一个示例

在开始复杂模拟之前,我们需要验证NS-3是否安装成功。NS-3自带了一个简单的测试程序。
步骤1:运行Hello Simulator
在 ns-3.27 目录下,执行以下命令:
./waf --run hello-simulator


这个命令会编译并运行一个名为 hello-simulator 的简单程序。如果终端输出 “Hello Simulator”,则表明NS-3安装和基本环境配置成功。
步骤2:运行教程示例


上一节我们验证了基础环境,本节我们来看看如何运行一个真正的网络模拟示例。NS-3在 examples/tutorial/ 目录下提供了一系列循序渐进的教程。

我们以第一个教程文件 first.cc 为例。运行它的标准流程是将其复制到 scratch/ 文件夹。
操作流程如下:

- 定位源文件:
first.cc文件位于ns-3.27/examples/tutorial/目录下。 - 复制到scratch:使用
cp命令将其复制到scratch/文件夹。
(视频中也演示了在图形界面中直接复制粘贴的方法。)cp examples/tutorial/first.cc scratch/ - 编译并运行:在
ns-3.27目录下,执行以下命令:
命令执行后,NS-3会编译./waf --run scratch/firstscratch/文件夹下的程序并运行。你将看到模拟输出的结果,例如客户端发送和接收数据包的时间与大小信息。
总结

本节课中,我们一起学习了NS-3的入门第一步。我们明确了核心工作目录 ns-3.27,了解了 scratch/, src/, build/, examples/ 等关键文件夹的作用。最重要的是,我们通过运行 hello-simulator 验证了安装,并掌握了将示例程序(如 first.cc)复制到 scratch/ 文件夹后,使用 ./waf --run scratch/<程序名> 命令来运行模拟的标准流程。这为我们后续深入学习NS-3的编程和模拟打下了坚实的基础。在下一节,我们将详细分析 first.cc 的源代码结构。
26:计算机网络入门 🖥️
在本节课中,我们将要学习计算机网络的基础知识。这是网络模拟学习的第一个主题。在深入模拟之前,我们需要了解一些关于计算机网络的基本概念。如果你已经是一名学生并掌握了网络基础知识,可以跳过此部分,以便更专注于网络的实际模拟。本节我们将介绍什么是计算机网络、不同的网络拓扑结构以及OSI模型各层的功能。

数据通信基础

上一节我们介绍了课程概述,本节中我们来看看数据通信是如何工作的。数据通信是网络的基础,它描述了源(发送方)和目的地(接收方)之间如何交换数据包。


数据通信涉及五个基本组件:消息、发送方、接收方、传输介质和协议。

以下是这五个组件的详细说明:
- 消息:指需要被传递的信息。常见形式包括文本、数字、图片、音频和视频。
- 发送方:指发送数据消息的设备。它可以是计算机、电话、无线电或摄像机等。
- 接收方:指接收消息的设备。
- 传输介质:指消息传输的路径。它可以是有线的(如以太网、光纤、双绞线),也可以是无线的(如无线电波、蜂窝网络)。
- 协议:指管理数据通信的一套规则。它代表了通信设备之间的约定。没有协议,两台设备可能连接在一起,但无法进行通信。
数据流方向
了解了数据通信的基本组件后,我们来看看数据流动的方向。数据流方向有三种基本模式:单工、半双工和全双工。

以下是三种模式的说明:
- 单工:通信只能在一个方向上进行,反向通信不可能。一个典型的例子是大型机计算机,数据流方向是单向的。
- 半双工:在任何一个给定的时间点,只能进行单向通信。在第一个时间段,消息从A流向B;在下一个时间段,消息可以从B流向A。在给定时刻,双方不能同时传输数据包。
- 全双工:源和目的地可以在同一时间点交换数据包,双方能够同时进行通信。
网络拓扑结构
接下来,我们将探讨网络拓扑结构。拓扑结构是指所有链路和节点之间关系的几何表示,它定义了网络节点如何相互连接。
主要有四种类型的拓扑结构:网状拓扑、星型拓扑、总线拓扑和环型拓扑。

网状拓扑

在网状拓扑中,你可以看到这里有五个站点(节点),它们彼此直接相连。例如,节点1连接到节点2、3、4、5。这意味着每个节点都与其他每个节点有专用连接。


网状拓扑的特点是:每个设备都有一条到其他所有设备的专用点对点链路。该链路只承载它所连接的两个设备之间的流量,通常使用全双工模式。

星型拓扑
星型拓扑意味着我们有一个集线器或交换机。就像大多数校园网络一样,每个实验室的计算机都连接到一个位于房间角落的集线器或交换机。

在星型拓扑中,每个设备都有一条专用的点对点链路,仅连接到一个称为集线器(或交换机)的中心控制器。控制器充当交换站。如果一个设备想向另一个设备发送数据,它会将数据发送给控制器,然后控制器将数据中继到另一个连接的设备。所有通信都通过这个中心控制器(交换机)进行。
总线拓扑
第三种是总线拓扑。总线拓扑是多点连接的。你可以看到这里有一个抽头,那里有一个抽头,还有电缆末端。节点像这样连接在一条总线上。
总线拓扑的特点是:一条长电缆充当主干,链接所有设备。网络节点通过引入线(抽头和分支线)连接到总线电缆。每个站点通过引入线连接到总线。

环型拓扑
环型拓扑连接成一个环。在环型拓扑中,每个设备仅与其两侧的两个设备有点对点连接。信号沿环单向从一个设备传递到另一个设备,直到到达目的地。

环型拓扑在容错方面非常有优势。如果任何一个特定站点发生故障,你仍然能够通过邻近的站点传输数据。因此,环型拓扑在高强度网络互连中非常有利。
思考与练习
现在,我们来看一些供学习者思考的问题。

以下是两个思考题:
- 我们的Wi-Fi网络遵循哪种网络拓扑?
- 宽带网络遵循哪种拓扑?如果你家中有宽带连接,可以检查你的宽带路由器信息,或询问你的互联网服务提供商他们遵循哪种网络结构。
感谢各位听众和学习者。这是第一个基础主题。如果你已经熟悉计算机网络,可以跳过这部分内容。

本节课中我们一起学习了计算机网络的基本概念,包括数据通信的五个组件、三种数据流方向(单工、半双工、全双工)以及四种主要的网络拓扑结构(网状、星型、总线、环型)。这些基础知识是后续进行网络模拟的重要前提。
27:IEEE标准与标准化的必要性 🏗️

在本节课中,我们将学习网络标准化的核心概念,特别是IEEE 802系列标准。我们将探讨为什么需要标准化,并详细介绍从有线到无线网络的各种关键标准。
概述
标准化是网络技术发展的基石。它确保了不同厂商生产的设备能够相互通信和协作。本节课将重点介绍IEEE 802标准系列,这是定义局域网和城域网技术的主要标准。

为什么需要标准化?
上一节我们概述了标准化的意义,本节中我们来看看标准化的具体必要性。标准化主要解决以下核心问题:
以下是标准化的主要目的:
- 互操作性:确保不同厂商生产的网络设备(如交换机、路由器、集线器、网关)能够相互通信和协作。
- 厂商独立性:在设计和制造产品时,所有厂商必须遵循共同的标准。这为产品设计提供了一个共同的基础,确保所有新产品都遵守既定的标准化建议。
主要标准组织
在了解了标准化的必要性后,我们来看看制定这些标准的主要组织。主要有两个标准组织与网络技术密切相关:
以下是两个关键的标准组织:
- 国际标准化组织:该组织制定了著名的OSI参考模型。此外,ISO的成员ANSI负责制定从编程语言到磁盘驱动器的标准,例如C++语言标准。
- 电气和电子工程师协会:这是我们今天重点讨论的标准组织。IEEE拥有超过30万名会员,其计算机学会的会员就超过10万。IEEE 802系列是局域网和城域网的主要标准。
IEEE 802标准详解
现在,让我们深入探讨IEEE 802系列中的具体标准。我们将逐一介绍从传统有线网络到现代无线网络的关键协议。
以下是IEEE 802系列的主要标准:
-
IEEE 802.1 - 网桥
- 该标准涉及局域网的整体架构、网络寻址、网络管理以及网桥标准。网桥用于连接多个网络段。
-
IEEE 802.2 - 逻辑链路控制
- LLC是数据链路层的子层,与介质访问控制协同工作,负责设备间的数据包通信。
-
IEEE 802.3 - 以太网
- 这是应用最广泛的有线局域网标准。它采用带冲突检测的载波侦听多路访问技术。初始速度为10 Mbps,现已发展到10 Gbps甚至更高。
- 代码示例:
if (collision_detected) { backoff_and_retransmit(); }
-
IEEE 802.4 & 802.5 - 令牌总线和令牌环
- 这些是早期的局域网技术(如令牌环,速度4/16 Mbps),现已基本被淘汰。
-
IEEE 802.11 - 无线局域网
- 这就是我们熟知的Wi-Fi标准。它适用于手机、笔记本电脑、智能家居设备等。该标准家族经历了多次演进:
- 802.11a/b/g:早期标准,工作在2.4 GHz免费频段,速度较慢(如11 Mbps, 54 Mbps)。
- 802.11n:引入了多输入多输出技术,速度提升至最高600 Mbps,同时支持2.4 GHz和5 GHz频段。
- 802.11ac:进一步提升了速度和容量,支持多用户MIMO,速度可达千兆级别。
- 其他相关标准:
802.11e(服务质量)、802.11i(安全增强)等。
- 这就是我们熟知的Wi-Fi标准。它适用于手机、笔记本电脑、智能家居设备等。该标准家族经历了多次演进:
-
IEEE 802.15 - 无线个域网
- 该系列标准用于短距离设备互联。
- 802.15.1:蓝牙技术的基础。
- 802.15.4:适用于物联网和无线传感器网络,如Zigbee协议。
-
其他IEEE 802标准
802.16:无线城域网。802.21:支持不同网络间切换的移动性协议。802.22:无线区域网。
总结与思考
本节课中,我们一起学习了网络标准化的必要性以及IEEE 802标准系列的核心内容。从确保互操作性的以太网到定义现代无线连接的Wi-Fi和蓝牙,这些标准构成了我们日常使用网络的基础。
最后,请思考一个问题:您的手机或笔记本电脑支持哪些具体的IEEE 802.11标准(例如802.11ac, 802.11ax)? 了解设备支持的标准有助于理解其网络性能。
28:详解third.cc文件

在本节课中,我们将学习NS3中一个名为third.cc的示例程序。该程序集成了点对点网络、CSMA局域网和无线网络三种网络拓扑,并演示了如何使用Wireshark、Trace Metrics和NetAnim等工具进行网络模拟分析。


概述
third.cc是NS3自带的一个综合示例,它在一个模拟场景中同时创建了三种不同类型的网络节点:点对点节点、CSMA总线节点和无线节点。通过这个例子,我们可以学习如何配置复杂的网络拓扑、安装协议栈、设置应用程序以及生成和分析网络流量数据。

上一节我们介绍了基础的网络模拟,本节中我们来看看如何构建一个包含多种网络类型的综合场景。
准备工作
首先,我们需要将示例文件复制到NS3的scratch目录下,这是运行自定义脚本的标准位置。
cp examples/tutorial/third.cc scratch/
完成复制后,我们可以进入NS3的根目录,使用以下命令编译并运行该脚本:
./waf --run scratch/third
首次运行可能需要一些编译时间。运行成功后,终端会输出模拟过程的信息,例如在特定时间点发送了多少字节的数据包。
代码结构解析
现在,让我们深入查看third.cc文件的内容,理解其各个组成部分。
头文件与全局声明
程序开头包含了NS3各个模块所需的头文件。
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/ssid.h"
接下来,在main函数中定义了一些控制模拟行为的变量。
bool verbose = true;
uint32_t nCsma = 3;
uint32_t nWifi = 3;
bool tracing = false;
verbose: 控制是否输出详细日志。nCsma: 定义CSMA网络中的节点数量(不包括与P2P网络共享的节点)。nWifi: 定义无线网络中的站点节点数量。tracing: 控制是否启用数据包追踪以生成PCAP文件。
创建网络节点
程序创建了三种网络的节点容器。
- 点对点节点:创建了两个节点(n0, n1)。
- CSMA节点:创建了
nCsma个节点,并将P2P节点中的n1也加入其中,因此CSMA总线上一共有nCsma + 1个节点。 - 无线节点:创建了
nWifi个站点节点(如n5, n6, n7)和一个接入点节点(AP)。接入点节点由P2P节点中的n0担任。
这构成了一个互联的网络拓扑:P2P网络连接n0和n1;n1同时属于CSMA网络;n0同时作为无线网络的接入点。
配置网络设备与信道
对于每种网络,都使用对应的Helper类来配置设备属性和安装网络设备。
- 点对点网络:使用
PointToPointHelper设置链路的数据速率和延迟。PointToPointHelper pointToPoint; pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); - CSMA网络:使用
CsmaHelper设置总线的数据速率和延迟。CsmaHelper csma; csma.SetChannelAttribute("DataRate", StringValue("100Mbps")); csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560))); - 无线网络:配置稍复杂,需要设置物理层、MAC层和移动模型。
- 使用
YansWifiChannelHelper和YansWifiPhyHelper配置无线信道和物理层。 - 使用
WifiMacHelper为站点节点和接入点节点分别设置MAC层参数,例如SSID。 - 使用
MobilityHelper为无线站点节点设置移动模型(如RandomWalk2dMobilityModel),为接入点节点设置固定位置模型。
- 使用
安装协议栈与应用
在所有节点上安装Internet协议栈(TCP/IP)。
InternetStackHelper stack;
stack.Install(p2pNodes);
stack.Install(csmaNodes);
stack.Install(wifiStaNodes);
stack.Install(wifiApNode);
然后,为节点分配IP地址。
Ipv4AddressHelper address;
address.SetBase("172.11.1.0", "255.255.255.0"); // P2P网络
address.Assign(p2pDevices);
address.SetBase("172.11.2.0", "255.255.255.0"); // CSMA网络
address.Assign(csmaDevices);
address.SetBase("172.11.3.0", "255.255.255.0"); // 无线网络
address.Assign(staDevices);
address.Assign(apDevices);
接着,创建了一个UDP回声服务器应用,安装在CSMA网络的最后一个节点(n4)上。
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma));
serverApps.Start(Seconds(1.0));
serverApps.Stop(Seconds(10.0));
同时创建了一个UDP回声客户端应用,安装在无线网络的最后一个站点节点(n7)上,并让它向服务器发送数据包。
UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue(1));
echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));
ApplicationContainer clientApps = echoClient.Install(wifiStaNodes.Get(nWifi - 1));
clientApps.Start(Seconds(2.0));
clientApps.Stop(Seconds(10.0));
启用追踪与运行模拟


如果tracing变量设为true,程序会启用PCAP文件追踪,这将生成可供Wireshark分析的数据包捕获文件。
if (tracing) {
pointToPoint.EnablePcapAll("third");
phy.EnablePcap("third", apDevices.Get(0));
csma.EnablePcap("third", csmaDevices.Get(0), true);
}

最后,设置模拟的起止时间并运行。
Simulator::Stop(Seconds(10.0));
Simulator::Run();
Simulator::Destroy();


使用分析工具
运行模拟后,我们可以利用多种工具分析结果。
Wireshark分析
当启用追踪后,会生成.pcap文件。使用Wireshark打开这些文件(例如third-0-0.pcap),可以直观地查看数据包的详细内容,如源/目的地址、协议类型、时序等。对于无线网络数据包,还可以分析信标帧等信息。
Trace Metrics分析



除了PCAP文件,我们还可以生成ASCII格式的追踪文件进行更灵活的分析。以下是创建追踪流的示例代码:

AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll(ascii.CreateFileStream("third-p2p.tr"));
csma.EnableAsciiAll(ascii.CreateFileStream("third-csma.tr"));
phy.EnableAsciiAll(ascii.CreateFileStream("third-wifi.tr"));
使用Trace Metrics工具(一个Java应用程序)可以处理这些.tr文件。它能提供丰富的统计信息,如总发送/接收包数、吞吐量、端到端延迟等,并支持将数据图表化导出。


NetAnim网络动画
为了可视化网络拓扑和节点间的数据流,我们可以使用NetAnim工具。这需要在代码中添加NetAnim模块头文件并配置节点位置。
#include "ns3/netanim-module.h"
...
AnimationInterface anim("third.xml");
anim.SetConstantPosition(csmaNodes.Get(0), 10.0, 10.0);
anim.SetConstantPosition(wifiStaNodes.Get(0), 30.0, 50.0);
// ... 为其他节点设置位置
运行模拟后会生成third.xml文件,使用NetAnim打开该文件,即可看到一个动态的网络模拟动画,可以观察节点的移动和数据包的传输过程。
总结


本节课中我们一起学习了NS3的third.cc综合示例。通过这个例子,我们掌握了如何构建包含点对点、CSMA和无线网络的混合拓扑,如何配置节点属性、安装协议栈和应用,以及如何利用Wireshark、Trace Metrics和NetAnim这三种强大的工具来捕获、统计和可视化网络模拟数据。这些技能是进行复杂网络协议研究和性能评估的基础。建议学习者尝试修改代码中的参数(如节点数量、IP地址、数据速率等),并观察模拟结果的变化,以加深理解。
29:在Ubuntu 20.04上安装NS-3.31 🛠️
在本节课中,我们将学习如何在64位Ubuntu 20.04操作系统上安装NS-3.31网络模拟器。我们将提供详细的逐步指导,确保初学者能够顺利完成安装。
概述
NS-3.31是网络模拟器3的一个版本。由于Python 2已停止支持,安装过程需要适配Python 3。本教程将指导你完成从系统更新到编译NS-3.31的全部步骤。
安装步骤
上一节我们介绍了课程目标,本节中我们来看看具体的安装步骤。以下是安装NS-3.31所需的完整命令序列。
首先,确保你有一个新安装的Ubuntu 20.04系统。打开终端,执行以下命令来更新系统并安装必要的构建工具。
sudo apt update
sudo apt install build-essential autoconf automake libxmu-dev


build-essential 包含了编译任何应用程序所需的基本软件。autoconf 和 automake 是自动化配置工具。libxmu-dev 是用于图形性能的开发库。
接下来,安装一系列NS-3.31运行所依赖的软件包。以下是需要安装的包列表。
sudo apt install gcc g++ python python3 python3-dev pkg-config sqlite3 cmake
sudo apt install python3-setuptools git mercurial qt5-default
sudo apt install gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz
sudo apt install gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc
sudo apt install libopenmpi-dev libxml2 libxml2-dev libc6-dev libc6-dev-i386
sudo apt install libclang-dev llvm-dev automake python3-pip
sudo apt install libgtk-3-dev vtun lxc uml-utilities
sudo apt install libboost-signals-dev libboost-filesystem-dev
sudo apt install wireshark

在安装Wireshark时,系统会询问是否允许非超级用户捕获数据包。根据你的安全策略选择“是”或“否”。
安装过程需要下载约442MB的数据,具体时间取决于你的网速。
配置与编译NS-3.31
所有依赖包安装完成后,我们就可以开始配置和编译NS-3.31了。首先,需要获取NS-3.31的源代码。

假设你已经从官网下载了 ns-allinone-3.31.tar.bz2 文件,并将其放置在 ~/Downloads 目录下。请将其复制到你的主目录并解压。
cp ~/Downloads/ns-allinone-3.31.tar.bz2 ~/
cd ~
tar -xjf ns-allinone-3.31.tar.bz2

解压后,你会得到一个名为 ns-allinone-3.31 的文件夹。进入该文件夹,准备构建NS-3。


cd ns-allinone-3.31

现在,运行构建脚本。以下命令将启用示例程序并进行构建。

./build.py --enable-examples --enable-tests
构建过程会编译大量模块,可能需要10到20分钟。构建完成后,终端会显示已构建和未构建的模块列表。
在本次安装中,有五个模块可能不会被构建:
briteclickopenflowvisualizer
visualizer 是NS-3内置的动画工具,openflow 用于软件定义网络,click 是模块化路由器。对于初学者的大多数实验,这些模块不是必需的。
验证安装


构建成功后,我们需要验证NS-3是否安装正确。进入NS-3的主目录并运行一个简单的测试。
cd ns-3.31
./waf --run hello-simulator
如果安装成功,你将看到输出 “Hello Simulator”。这表明核心模拟器已正常工作。
为了进一步测试,我们可以运行教程中的示例程序。

cd examples/tutorial
cp first.cc second.cc
./waf --run first
运行 first 示例(一个简单的点对点网络模拟)可以确认更多功能是否正常。关于此示例的详细解释,可以参考本系列的其他教程视频。
总结
本节课中我们一起学习了在全新的Ubuntu 20.04系统上安装NS-3.31网络模拟器的完整流程。我们首先更新了系统并安装了所有必要的依赖包,然后下载、配置并编译了NS-3.31源代码,最后通过运行测试程序验证了安装成功。遵循这些步骤,你应该能够搭建起可用的NS-3.31仿真环境,为后续的网络协议和拓扑实验做好准备。
30:使用Ns3进行FANET模拟与3D移动模型 🚁
在本节课中,我们将学习如何使用网络模拟器3(Ns3)来模拟飞行自组织网络(FANET)。我们将重点介绍如何使用Ns3内置的3D移动模型——Gauss-Markov移动模型,来模拟无人机等飞行节点的三维运动。
概述
飞行自组织网络是移动自组织网络的一种特殊形式,其节点是无人机等飞行器。模拟这类网络的关键在于准确地模拟节点在三维空间中的移动。Ns3提供了Gauss-Markov移动模型来支持这种3D移动模拟。本节教程将指导你如何设置一个包含20个无线节点的FANET场景,配置3D移动模型,并运行模拟以生成网络流量和动画。
代码结构与配置
以下是构建FANET模拟的核心代码结构。我们将使用802.11b标准,并配置Ad-hoc模式的Wi-Fi MAC层,因为FANET中的节点需要直接相互通信。
网络设备与协议配置:
// 创建20个节点
NodeContainer c;
c.Create(20);
// 配置Wi-Fi标准、MAC和物理层
WifiHelper wifi;
wifi.SetStandard(WIFI_STANDARD_80211b);
WifiMacHelper mac;
mac.SetType("ns3::AdhocWifiMac"); // 使用Ad-hoc模式
YansWifiPhyHelper wifiPhy;
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
wifiPhy.SetChannel(wifiChannel.Create());
// 安装网络设备
NetDeviceContainer devices = wifi.Install(wifiPhy, mac, c);
上一节我们介绍了网络的基本配置,本节中我们来看看如何设置路由和IP地址。
路由与IP地址分配:
我们使用AODV路由协议,并为所有节点分配IP地址。
// 启用AODV路由协议
InternetStackHelper internet;
AodvHelper aodv;
internet.SetRoutingHelper(aodv);
internet.Install(c);
// 分配IP地址
Ipv4AddressHelper ipv4;
ipv4.SetBase("192.168.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = ipv4.Assign(devices);


配置3D移动模型


接下来是核心部分:配置3D移动模型。我们将使用Gauss-Markov模型,它允许节点在三维空间中以随机速度和方向移动。


以下是配置Gauss-Markov 3D移动模型的关键参数:
MobilityHelper mobility;
mobility.SetMobilityModel("ns3::GaussMarkovMobilityModel",
"Bounds", BoxValue(Box(0, 100, 0, 100, 0, 100)), // 三维空间边界 (x, y, z)
"TimeStep", TimeValue(Seconds(0.5)), // 时间步长
"Alpha", DoubleValue(0.85), // 记忆参数
"MeanVelocity", RandomVariableValue(UniformVariable(80, 200)), // 平均速度范围
"MeanDirection", RandomVariableValue(UniformVariable(0, 6.2831853)), // 平均方向
"MeanPitch", RandomVariableValue(UniformVariable(0, 0.05)), // 平均俯仰角
"NormalVelocity", StringValue("ns3::NormalRandomVariable[Mean=0.0|Variance=0.0|Bound=0.4]"),
"NormalDirection", StringValue("ns3::NormalRandomVariable[Mean=0.0|Variance=0.0|Bound=0.4]"),
"NormalPitch", StringValue("ns3::NormalRandomVariable[Mean=0.0|Variance=0.0|Bound=0.4]"));
// 设置节点的初始位置分配器(在100x100x100的立方体内随机分布)
mobility.SetPositionAllocator("ns3::RandomBoxPositionAllocator",
"X", StringValue("ns3::UniformRandomVariable[Min=0|Max=100]"),
"Y", StringValue("ns3::UniformRandomVariable[Min=0|Max=100]"),
"Z", StringValue("ns3::UniformRandomVariable[Min=0|Max=100]"));
// 将移动模型安装到所有节点上
mobility.Install(c);
应用层与数据捕获
配置好移动性后,我们需要为节点生成流量,并设置工具来捕获和分析模拟数据。
UDP应用生成:
我们设置一个UDP客户端-服务器应用,其中节点0作为服务器,节点1作为客户端。
// 创建UDP回声服务器(端口9)
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(c.Get(0));
serverApps.Start(Seconds(1.0));
serverApps.Stop(Seconds(10.0));
// 创建UDP回声客户端
UdpEchoClientHelper echoClient(interfaces.GetAddress(0), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue(100));
echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));
ApplicationContainer clientApps = echoClient.Install(c.Get(1));
clientApps.Start(Seconds(2.0));
clientApps.Stop(Seconds(10.0));
数据捕获与分析工具:
为了观察和分析模拟结果,我们启用数据包捕获(PCAP)和网络动画。
// 启用PCAP捕获(用于Wireshark分析)
wifiPhy.EnablePcap("fanet3d", devices);
// 启用ASCII跟踪(用于自定义分析)
AsciiTraceHelper ascii;
wifiPhy.EnableAsciiAll(ascii.CreateFileStream("fanet3d.tr"));
// 启用NetAnim动画
AnimationInterface anim("fanet3d.xml");


运行模拟与结果分析
完成代码编写后,在Ns3环境中编译并运行脚本。模拟结束后,你会得到以下文件:
.pcap文件:可用Wireshark打开,进行数据包级别的协议分析(如吞吐量、延迟统计)。.tr文件:ASCII格式的跟踪文件,记录了每个数据包的发送、接收、丢弃等事件。.xml文件:NetAnim动画文件,可以直观地看到20个节点在三维空间中的移动和通信过程。
通过比较使用2D随机移动模型和3D Gauss-Markov模型的模拟结果,你可以观察到节点移动模式对网络连接性和数据流产生的不同影响。在3D模型中,节点在高度上的变化使得网络拓扑更加动态。
总结
本节课中我们一起学习了如何在Ns3中构建一个FANET模拟场景。核心内容包括:
- 配置基于802.11b的Ad-hoc无线网络。
- 使用AODV路由协议。
- 重点配置并应用了Gauss-Markov 3D移动模型来模拟飞行节点的运动。
- 设置了UDP应用层流量。
- 利用PCAP、ASCII跟踪和NetAnim工具来捕获和分析模拟结果。

通过本教程,你掌握了使用Ns3进行三维移动网络模拟的基本方法,为研究无人机网络、飞行汽车通信等前沿课题打下了基础。你可以尝试修改移动模型参数、节点数量或通信协议,来探索不同场景下的网络性能。
31:网络性能指标


在本节课中,我们将学习网络性能评估中常用的核心指标。这些指标对于理解和优化有线及无线网络的性能至关重要。

概述


网络性能指标是衡量网络通信质量与效率的关键参数。无论是对于有线网络还是无线网络,理解这些指标都有助于我们诊断问题、优化配置。本节课程将详细介绍吞吐量、延迟、丢包率、抖动等核心概念。



吞吐量 📈
吞吐量是衡量网络性能的基础指标。它指的是在单位时间内,从一个网络节点成功传输到另一个网络节点的数据量。
吞吐量通常以比特每秒或字节每秒为单位。小写字母 b 代表比特,大写字母 B 代表字节。例如,Mbps 表示兆比特每秒,MBps 表示兆字节每秒。



公式:吞吐量 = 传输的数据量 / 时间
吞吐量与有效吞吐量
与吞吐量相关的一个概念是有效吞吐量。两者的区别在于:
- 吞吐量:衡量的是通过网络链路传输的所有数据总量,无论其是否有用。
- 有效吞吐量:特指在应用层,成功传输到目的地的有用信息的数据量。


有效吞吐量通常只在应用层进行测量,而吞吐量可以在网络层、传输层等各个层面进行测量。
瞬时吞吐量与平均吞吐量

为了理解吞吐量的计算,我们来看一个例子。
假设节点A和节点B通过一条有线链路连接。该链路的数据速率为 5 Mbps,延迟为 2 毫秒。这意味着网络可以在 2 毫秒内将 5 Mb 的数据从 A 点传输到 B 点。基于这些值,我们可以计算出从源节点到目的节点传输数据包的速度,这被称为瞬时吞吐量。



现在,考虑一个更复杂的场景:节点A连接到节点B,节点B再连接到节点C。A到B的瞬时吞吐量为 T1,B到C的瞬时吞吐量为 T2。那么,从A到C的平均吞吐量可以通过计算 T1 和 T2 的平均值来获得。

公式:平均吞吐量 = (T1 + T2) / 链路数量


吞吐量是一个强大的性能指标。网络中的高延迟、大量数据包拥塞以及缺乏拥塞控制机制,都会显著影响吞吐量。


端到端延迟 ⏱️

上一节我们介绍了吞吐量,本节我们来看看另一个关键指标:延迟。延迟,特别是端到端延迟,是指数据包从源节点传输到目的节点所花费的总时间。
端到端延迟是路径上所有链路和中间节点产生的延迟之和。延迟主要分为两种类型:
-
传输延迟:在特定链路上发送一个数据包所需的时间。如果以速率
R(比特/秒)发送B比特的数据,则传输延迟为B / R。
公式:传输延迟 = 数据包大小 / 链路带宽 -
传播延迟:信号在物理介质中传播所花费的时间。它取决于链路的长度和信号在介质中的传播速度(例如,光在光纤中的速度)。
延迟计算示例
让我们通过一个例子来计算端到端延迟。考虑一个从源节点 S 到目的节点 D 的网络路径,中间经过节点 A、B、C。
- S -> A:有线链路,带宽 10 Mbps,延迟 2 ms
- A -> B:无线链路(延迟可变,此处假设为特定值)
- B -> C:有线链路,带宽 10 Mbps,延迟 1 ms
- C -> D:有线链路,带宽 100 Mbps,延迟 1 ms
假设我们测量或估算出每段链路的延迟分别为 D1、D2、D3、D4。那么,从 S 到 D 的端到端延迟就是这些延迟值的总和。

公式:端到端延迟 = D1 + D2 + D3 + D4



响应时间/网络延迟 🔄

响应时间,也称为网络延迟,在技术上是指系统对给定输入做出反应所需的时间。在网络中,它衡量的是数据到达其目的地所需的时间。

网络延迟通常以往返时间 来衡量。RTT 是指信息从源到达目的地,然后再返回源所需的总时间。这类似于使用 ping 命令测试网站时得到的时间。


公式:RTT = 数据包前往目的地的耗时 + 数据包返回源地的耗时
较低的 RTT 值意味着更好的网络响应速度和更快的互联网连接。高延迟是影响吞吐量的主要因素之一,通常由链路拥塞引起。



数据包丢失与丢弃 📦
接下来,我们探讨数据包丢失和丢弃这两个相关但略有不同的概念。

- 数据包丢失:指在网络中传输的数据包未能到达目的地。丢失可能发生在路径的任何地方。
- 数据包丢弃:通常发生在网络节点(如路由器)的接口处。当接口的缓冲区已满,无法容纳新到达的数据包时,该数据包就会被丢弃。

数据包丢失可能由多种原因造成,例如链路拥塞或无线网络中的无线电干扰。数据包丢弃则通常是由于接收节点的缓冲区溢出,或者节点出于安全策略等原因主动拒绝数据包。
数据包投递率 📊

数据包投递率是衡量网络可靠性的重要指标。它是目的节点成功接收的数据包数量与源节点发送的数据包总数之比。

公式:PDR = (成功接收的数据包数 / 发送的数据包总数) * 100%
理想的 PDR 是 100%,表示所有发送的数据包都被成功接收。PDR 下降通常意味着网络性能变差。

抖动 🎵


抖动是评估网络性能,尤其是对 VoIP、视频通话等实时多媒体应用至关重要的一个参数。当数据包到达目的地的时间间隔不均匀时,就会发生抖动。
抖动是由于某些数据包被延迟、丢失或失序到达,导致信息混乱造成的。例如,在语音通话中,高抖动会导致声音断断续续。

典型的网络抖动应低于 30 毫秒。如果抖动在 30 到 75 毫秒之间,可能会影响通话质量。超过 75 毫秒则通常需要采取措施改善网络。
抖动可能由网络拥塞、无线信号不稳定或硬件性能不佳引起。减少抖动的方法包括:
- 在网络设备上配置抖动缓冲区。
- 升级互联网服务或硬件(如路由器)。
总结
在本节课中,我们一起学习了评估网络性能的核心指标:
- 吞吐量:单位时间内成功传输的数据量。
- 有效吞吐量:应用层成功传输的有用数据量。
- 端到端延迟:数据包从源到目的地的总耗时。
- 响应时间/延迟:通常用往返时间衡量。
- 数据包丢失与丢弃:数据包未能到达目的地的不同情形。
- 数据包投递率:衡量网络传输可靠性的比率。
- 抖动:数据包到达时间的变化,影响实时应用。



理解这些指标将帮助您更好地分析、诊断和优化网络性能。在未来的课程中,我们将结合无线网络的具体场景进一步探讨这些性能指标的应用。
32:NS3中的链路状态路由与有线网络 🌐
概述
在本节课中,我们将学习如何在网络模拟器3(NS3)中实现链路状态路由协议,并应用于一个有线网络场景。我们将通过构建一个包含五个节点和六条链路的网络拓扑,配置每条链路的带宽和延迟参数,然后运行模拟来观察数据包的传输路径,并分析网络性能。
网络设计与链路状态路由原理
上一节我们介绍了链路状态路由的基本概念。本节中,我们来看看如何在NS3中具体实现它。
链路状态路由协议(如OLSR)的核心思想是每个路由器都了解整个网络的拓扑结构,通过交换链路状态信息,每个节点可以独立计算到所有目的地的最短路径。计算最短路径的常用算法是Dijkstra算法,其核心公式是寻找从源节点到所有其他节点的最小成本路径。
我们将设计一个包含五个路由器(R0, R1, R2, R3, R4)的网络。目标是找出从R1到R2的最优路径。根据配置的链路成本(由带宽和延迟决定),路径可能有两种选择:
- R1 -> R0 -> R2
- R1 -> R4 -> R3 -> R0 -> R2
通过模拟,我们可以验证NS3中的路由协议是否会选择理论上的最短路径。
以下是网络拓扑中每条链路的特性配置:
- R0 - R1: 延迟 2ms, 带宽 10 Mbps
- R1 - R4: 延迟 10ms, 带宽 5 Mbps
- R4 - R3: 延迟 2ms, 带宽 2 Mbps
- R3 - R0: 延迟 5ms, 带宽 5 Mbps
- R0 - R2: 延迟 1ms, 带宽 1 Mbps
- R2 - R3: 延迟 50ms, 带宽 50 Mbps
模拟实现步骤
要实现并观察这个链路状态路由模拟,我们需要完成以下几个核心步骤。
以下是具体的操作流程:
- 编写源代码:创建一个C++程序来定义网络拓扑、节点、链路、应用层流量并启用路由协议。
- 编译程序:使用NS3的编译系统(
./ns3)来编译我们编写的源代码文件。 - 运行模拟:执行编译后的程序,生成跟踪文件和数据包捕获文件。
- 可视化与分析:使用NetAnim工具查看网络动画,使用Trace-Metric等工具分析吞吐量等性能指标。
源代码详解
现在,让我们深入查看实现上述设计的NS3源代码的关键部分。
首先,程序包含了必要的头文件,并定义了诸如数据包大小、数据速率等参数。我们使用NS3命名空间。
// 示例参数定义
uint32_t packetSize = 210; // 字节
std::string dataRate = "448kbps"; // UDP流量生成速率
接着,创建五个网络节点。
NodeContainer c;
c.Create(5); // 创建5个节点:R0, R1, R2, R3, R4
然后,定义节点之间的连接(链路),总共六条。
NodeContainer n01 = NodeContainer(c.Get(0), c.Get(1));
NodeContainer n14 = NodeContainer(c.Get(1), c.Get(4));
// ... 类似地定义 n43, n30, n02, n23
配置链路状态路由和互联网协议栈。
// 启用链路状态路由协议 (OLSR)
OlsrHelper olsr;
// 创建静态路由辅助器,并与OLSR一起添加到协议列表中
Ipv4StaticRoutingHelper staticRouting;
Ipv4ListRoutingHelper list;
list.Add(staticRouting, 0);
list.Add(olsr, 10);
// 在所有节点上安装互联网协议栈
InternetStackHelper internet;
internet.SetRoutingHelper(list);
internet.Install(c);
接下来,使用PointToPointHelper为每条链路设置具体的延迟和带宽。
// 配置 R0-R1 链路
PointToPointHelper p2p01;
p2p01.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
p2p01.SetChannelAttribute("Delay", StringValue("2ms"));
NetDeviceContainer d01 = p2p01.Install(n01);
// ... 类似地配置其他五条链路
为所有网络设备分配IP地址。
Ipv4AddressHelper ip;
ip.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer i01 = ip.Assign(d01);
ip.SetBase("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer i14 = ip.Assign(d14);
// ... 为所有链路分配IP地址
创建UDP应用,从节点1向节点2发送数据。
// 设置UDP服务器(接收端)在节点2上
uint16_t port = 8000;
PacketSinkHelper sink("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), port));
ApplicationContainer sinkApp = sink.Install(c.Get(2));
// 设置UDP客户端(发送端)在节点1上
OnOffHelper client("ns3::UdpSocketFactory", InetSocketAddress(i02.GetAddress(1), port));
client.SetAttribute("DataRate", StringValue(dataRate));
client.SetAttribute("PacketSize", UintegerValue(packetSize));
ApplicationContainer clientApp = client.Install(c.Get(1));
为了可视化,我们使用AnimationInterface并设置节点位置。
AnimationInterface anim("lsr-animation.xml");
anim.SetConstantPosition(c.Get(0), 0, 50); // R0
anim.SetConstantPosition(c.Get(1), 50, 100); // R1
anim.SetConstantPosition(c.Get(2), 50, 0); // R2
anim.SetConstantPosition(c.Get(3), 50, 0); // R3 (调整后)
anim.SetConstantPosition(c.Get(4), 100, 50); // R4
最后,设置模拟时间并启动模拟。


Simulator::Stop(Seconds(30.0));
Simulator::Run();
Simulator::Destroy();
编译与运行模拟
源代码准备就绪后,下一步是将其编译并运行。


首先,将源代码文件(例如exp11.cc)保存到NS3目录下的scratch/文件夹中。然后打开终端,导航到NS3根目录进行编译。
cd ns-allinone-3.29/ns-3.29
./ns3 run scratch/exp11
编译成功后,程序会自动运行。运行结束后,会在当前目录生成跟踪文件(如lsr.tr)、数据包捕获文件(lsr.pcap)和网络动画文件(lsr-animation.xml)。
结果可视化与分析
模拟运行完成后,我们可以通过多种方式直观地查看和分析结果。


1. 使用NetAnim查看网络动画:
在终端中启动NetAnim,并加载生成的XML文件。
cd netanim-3.108
./NetAnim
在NetAnim界面中打开lsr-animation.xml文件,即可播放模拟动画。你可以看到数据包根据链路状态路由协议计算出的路径在网络中移动,验证R1到R2的数据流主要经由R0转发。

2. 使用Trace-Metric分析吞吐量:
Trace-Metric是一个基于Java的工具,用于分析NS3的跟踪文件。
cd trace-metric
java -jar trace-metric.jar
在打开的界面中,选择生成的lsr.tr文件。工具会解析文件,展示诸如节点吞吐量等信息。从分析结果可以看出,节点0、1、2有较高的吞吐量,而节点3、4的吞吐量较低,这与我们的网络流量路径(R1->R0->R2)相符。
3. 绘制吞吐量图表:
可以将Trace-Metric输出的吞吐量数据导出为CSV格式,然后使用电子表格软件(如LibreOffice Calc)绘制图表。图表会清晰显示各节点在模拟期间的吞吐量差异,直观反映网络流量的分布情况。

总结
本节课中我们一起学习了在NS3中配置和运行链路状态路由协议的全过程。我们从设计一个有线网络拓扑开始,为每条链路设置了带宽和延迟参数。然后,我们详细讲解了实现该模拟的NS3源代码,包括创建节点、配置链路、安装协议栈、设置应用以及启用可视化。接着,我们完成了程序的编译和运行。最后,我们利用NetAnim工具观察了数据包的路由路径,并使用Trace-Metric工具分析了网络的吞吐量性能。通过这个完整的示例,你可以掌握在NS3中进行路由协议仿真和基础网络性能分析的方法。
33:在Ubuntu 20.04中安装ns-3.34 🛠️

概述
在本节课中,我们将学习如何在Ubuntu 20.04操作系统上,一步一步地安装网络模拟器ns-3的最新版本ns-3.34。我们将涵盖从系统更新、依赖包安装到编译ns-3.34源码,并最终运行一个示例程序来验证安装是否成功的全过程。
准备工作与系统更新
首先,我们需要确保系统是最新的,并安装所有必要的依赖包。这是安装任何软件前的好习惯,可以避免潜在的兼容性问题。

打开一个终端,执行以下命令来更新软件包列表:
sudo apt update

更新完成后,我们将安装ns-3.34运行所需的一系列依赖包。以下是需要执行的命令,它会下载并安装大约152MB的软件包:
sudo apt install -y g++ python3 python3-dev pkg-config sqlite3 cmake python3-setuptools git qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc libopenmpi-dev autoconf cvs bzr unrar gdb valgrind uncrustify doxygen graphviz imagemagick texlive texlive-extra-utils texlive-latex-extra texlive-font-utils dvipng latexmk python3-sphinx dia gsl-bin libgsl-dev libgslcblas0 tcpdump sqlite sqlite3 libsqlite3-dev libxml2 libxml2-dev libgtk-3-dev vtun lxc uml-utilities libboost-all-dev

在安装依赖包的同时,我们可以去下载ns-3.34的源代码。


下载ns-3.34源代码
上一节我们准备好了系统环境,本节我们来获取ns-3.34的源代码。

访问ns-3的官方网站(https://www.nsnam.org/),找到下载页面,选择最新的ns-3.34版本进行下载。你也可以直接使用wget命令下载。下载完成后,你通常会得到一个名为 ns-allinone-3.34.tar.bz2 的压缩包。

将下载的压缩包移动到你的主目录(/home/你的用户名/)下,然后解压:
tar -xjvf ns-allinone-3.34.tar.bz2
解压后会生成一个名为 ns-allinone-3.34 的文件夹。为了简化路径,我们可以将其重命名为 ns3:
mv ns-allinone-3.34 ns3

配置与编译ns-3.34
现在我们已经有了源代码,接下来进入最关键的配置和编译阶段。这个过程会将源代码构建成可执行的程序。

首先,进入ns3目录:
cd ns3

然后,使用 ./waf 工具进行配置和编译。我们启用测试和示例程序,这对于学习和调试非常有帮助。执行以下命令:
./waf configure --enable-tests --enable-examples
这个命令会检查系统环境并配置编译选项。配置成功后,开始编译:
./waf build
编译过程会安装包括网络可视化工具(NetAnim)、Python绑定、Wireshark集成以及各种核心模块(如网络、路由、移动模型等)在内的多个组件。整个过程可能会持续较长时间(例如一小时左右),具体取决于你的电脑性能。
编译完成后,终端会显示成功构建的模块列表。可能会有一小部分可选模块(如OpenFlow、DPDK)因缺少依赖而未被构建,但这通常不影响ns-3的核心功能。

验证安装与运行示例
编译完成后,我们需要验证ns-3.34是否安装成功。一个很好的方法是运行一个自带的示例程序。
ns-3.34修复了之前版本中 vanet-routing-compare.cc 示例文件的一个编译错误。我们将运行这个示例来测试安装。
首先,进入示例文件所在的目录:
cd src/cvanet/examples
然后,将该示例程序复制到ns-3的临时运行目录(scratch)下:
cp vanet-routing-compare.cc ../../../scratch/
返回ns3主目录,并运行该程序:
cd ../../../
./waf --run scratch/vanet-routing-compare

如果安装成功,程序将开始运行。你会在终端看到模拟过程的输出信息,包括数据包的发送、接收和丢包统计。程序运行一段时间后,会输出诸如包投递率(PDR)和有效吞吐量(Goodput)等性能指标。这证明ns-3.34已经成功安装并可以正常工作。

你也可以将输出重定向到一个文件以便查看:
./waf --run scratch/vanet-routing-compare > output.txt 2>&1


总结
本节课中,我们一起完成了在Ubuntu 20.04上安装ns-3.34的全过程。我们首先更新了系统并安装了所有必要的依赖包,然后下载并解压了ns-3.34的源代码。接着,我们使用waf工具配置和编译了整个项目。最后,通过成功运行 vanet-routing-compare 示例程序,我们验证了安装是正确且可用的。


现在,你已经拥有了一个可以运行网络模拟实验的ns-3.34环境,可以开始探索更多的示例和创建你自己的仿真项目了。
34:在Ubuntu 22.04中安装NS3 3.36.1 🖥️
概述
在本节课中,我们将学习如何在Ubuntu 22.04操作系统上安装网络模拟器NS3的最新版本3.36.1。这个新版本引入了一个重要的变化:它移除了旧的Waf构建系统,转而使用CMake系统。因此,编译和运行脚本的命令与旧版本有所不同。本教程将提供完整的安装步骤,确保初学者能够顺利完成安装。
安装步骤
第一步:更新系统包管理器
首先,我们需要更新系统的包管理器,以确保能够获取到最新的软件包列表。这是安装任何新软件前的标准步骤。


请在终端中执行以下命令:
sudo apt update
第二步:安装必要的依赖包
接下来,我们需要安装NS3运行和编译所需的所有依赖软件包。以下命令将安装一个完整的软件包集合,安装完成后,您通常不需要再安装其他额外的软件。
以下是需要安装的软件包列表:
g++gccpython3python3-devpkg-configsqlite3cmakeninja-buildgitqtbase5-devqtchooserqt5-qmakeqtbase5-dev-toolsmercurial
您可以使用以下命令一次性安装它们:
sudo apt install g++ gcc python3 python3-dev pkg-config sqlite3 cmake ninja-build git qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools mercurial
第三步:下载并解压NS3
所有依赖安装完成后,我们需要从NS3的官方网站下载NS3 3.36.1的源代码压缩包。请注意,网站上也有旧版本,但旧版本可能仍在使用旧的Waf系统。如果您想使用新的CMake系统,请确保下载3.36.1或更高版本。

下载完成后,建议将压缩包解压到您的用户主目录。例如,如果您的用户名是user,主目录路径通常是/home/user。
您可以通过图形界面右键点击文件并选择“解压到...”来完成,也可以使用命令行。以下是解压命令:
tar -jxvf ns-allinone-3.36.1.tar.bz2
这个命令会将文件解压到当前目录下的ns-allinone-3.36.1文件夹中。

第四步:配置与编译NS3
现在,进入解压后生成的NS3主目录,开始配置和编译过程。
首先,使用cd命令进入目录:
cd ns-allinone-3.36.1/ns-3.36.1
然后,运行配置命令。这个命令会启用示例和测试,这对于学习和验证安装非常有用。
./ns3 configure --enable-examples --enable-tests
配置完成后,开始编译。这个过程可能需要一些时间,具体取决于您的硬件。在固态硬盘上可能需要10到15分钟,在虚拟机或机械硬盘上可能需要更长时间。
./ns3 build
提示:如果在虚拟机中编译过程因内存不足而停止,您可以尝试临时增加虚拟机的内存容量,完成安装后再降低。

第五步:测试安装是否成功
编译完成后,我们需要测试NS3是否能正常运行。新版本中,运行脚本的命令已从./waf改为./ns3。
首先,运行一个简单的测试程序来验证核心功能:
./ns3 run hello-simulator
如果安装成功,您将在终端看到“Hello Simulator”的输出。
上一节我们验证了核心安装,本节中我们来看看如何运行实际的网络模拟脚本。

第六步:运行网络模拟脚本
NS3自带了许多示例脚本,位于examples/tutorial目录下。为了运行我们自己的脚本,通常将其复制到scratch目录下。

例如,要运行一个名为first.cc的C++脚本,命令如下(注意不需要指定.cc扩展名):
./ns3 run scratch/first
如果要运行一个Python脚本,例如first.py,则必须指定完整的文件名和.py扩展名:
./ns3 run scratch/first.py
运行这些命令后,您将看到相应的网络模拟输出,这表明您的NS3环境已经完全配置好,可以开始使用了。
总结


本节课中我们一起学习了在Ubuntu 22.04上完整安装NS3 3.36.1的流程。关键点包括:使用sudo apt update和sudo apt install来准备环境;从官网下载并解压源代码;使用./ns3 configure和./ns3 build命令进行配置和编译;最后,使用./ns3 run命令来测试安装和运行模拟脚本。请记住,从NS3 3.36.1开始,旧的./waf命令已被新的./ns3命令取代。现在,您的NS3开发环境已经就绪,可以开始探索网络模拟了。
35:在Ubuntu中安装NS3(NS-3.35与NS-3.37)🚀

在本教程中,我们将学习如何在Ubuntu 22.04 LTS操作系统上安装两个版本的网络模拟器NS3:NS-3.35和NS-3.37。我们将从系统准备开始,逐步完成下载、编译和测试安装的全过程。
概述与准备工作
上一节我们介绍了本教程的目标。本节中,我们来看看安装前的准备工作。安装两个版本的原因是:NS-3.36及之后的版本从Waf构建框架切换到了CMake框架。为了同时支持基于旧Waf框架和新CMake框架的协议与应用实验,我们需要安装两个版本。
首先,假设你刚刚全新安装了Ubuntu 22.04。你需要更新系统包管理器并安装一系列NS3依赖的软件包。

以下是需要执行的初始命令和软件包列表:
sudo apt update
sudo apt install -y g++ python3 python3-dev pkg-config sqlite3 cmake python3-setuptools git qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc libopenmpi-dev autoconf cvs bzr unrar gdb valgrind uncrustify doxygen graphviz imagemagick texlive texlive-extra-utils texlive-latex-extra texlive-font-utils dvipng latexmk python3-sphinx dia gsl-bin libgsl-dev libgslcblas0 tcpdump sqlite sqlite3 libsqlite3-dev libxml2 libxml2-dev libgtk2.0-0 libgtk2.0-dev vtun lxc uml-utilities libboost-all-dev

这个安装过程可能需要一些时间,具体取决于你的系统配置和网络速度。
下载与解压NS3源码
准备工作完成后,我们需要获取NS3的源代码。你可以从nsnam.org官网下载,也可以从提供的博客或Github仓库获取。

假设我们已经将ns-allinone-3.37.tar.bz2和ns-allinone-3.35.tar.bz2两个压缩包下载并放到了用户主目录(/home/)下。

以下是解压文件的步骤:


- 在文件管理器中,分别对两个压缩包右键点击,选择“提取到此处”。
- 解压后会生成两个文件夹:
ns-allinone-3.37和ns-allinone-3.35。
现在,我们已经准备好了两个版本的源代码。

安装NS-3.37(CMake框架)
上一节我们准备好了源代码。本节中,我们首先安装基于CMake框架的NS-3.37。
进入NS-3.37的目录并执行构建命令:
cd ns-allinone-3.37
./ns3 configure --enable-examples --enable-tests
./ns3 build

这个过程可能需要15到35分钟,时间长短取决于你的系统是使用SSD还是传统硬盘。
构建完成后,我们需要验证安装是否成功。
以下是测试安装的步骤:

- 运行一个简单的示例:
./ns3 run hello-simulator。如果输出包含“Hello Simulator”,则初步成功。 - 运行教程中的示例。首先将示例文件复制到scratch目录:
cp examples/tutorial/first.cc scratch/。 - 运行该示例:
./ns3 run scratch/first。如果程序能成功编译并运行,输出网络配置信息,则说明安装成功。 - 此外,可以测试网络动画工具NetAnim:进入
netanim目录并运行./NetAnim,检查软件是否能正常启动。

如果以上测试都通过,说明NS-3.37已成功安装。
安装NS-3.35(Waf框架)及问题解决
成功安装NS-3.37后,我们接下来安装基于旧版Waf框架的NS-3.35。步骤类似,但可能会遇到一个特定的错误。
首先,进入NS-3.35目录并开始构建:
cd ../ns-allinone-3.35
./ns3 configure --enable-examples --enable-tests
./ns3 build
在构建过程中,你可能会遇到一个“Python binding generation error”。这是因为Python版本兼容性问题。
以下是解决此错误的步骤:

- 找到并编辑文件:
ns-3.35/bindings/python/ns3ns3gcccpython/cppyy/cp.py。 - 定位到第42行附近。将原来的
collections.Callable = collections这一行删除。 - 在相应位置添加以下两行代码:
import collections.abc collections.Callable = collections.abc.Callable - 保存文件,然后重新运行构建命令:
./ns3 build。
修正错误后,构建过程应该能顺利完成。
验证NS-3.35安装
构建完成后,同样需要对NS-3.35进行验证。注意,运行命令使用的是waf而不是ns3。

以下是验证安装的步骤:
- 运行基础测试:
./waf --run hello-simulator,应输出“Hello Simulator”。 - 复制并运行
first.cc示例:cp examples/tutorial/first.cc scratch/,然后执行./waf --run scratch/first。 - 测试Python脚本的运行。复制Python示例:
cp examples/tutorial/first.py scratch/。 - 运行Python脚本:
./waf --run scratch/first.py。注意,对于Python文件,运行命令中不需要额外的--pyrun参数,waf会自动识别。
如果所有命令都能成功执行并产生预期输出,则表明NS-3.35也安装成功。
总结
本节课中,我们一起学习了在Ubuntu 22.04系统上安装NS-3.35和NS-3.37两个版本网络模拟器的完整流程。我们首先准备了系统环境,然后分别下载和解压了源代码。接着,我们逐步编译并安装了基于CMake框架的NS-3.37,并进行了测试。随后,我们处理了安装基于Waf框架的NS-3.35时可能遇到的Python绑定生成错误,并最终成功验证了两个版本的安装。

现在,你的系统上已经同时具备了新旧两种构建框架的NS3环境,可以用于支持不同框架下的网络协议与应用的仿真实验。如果在安装过程中遇到其他问题,可以参考相关社区或博客寻求帮助。
36:第1:在Ubuntu 22.04中安装NS-3.38 🖥️
在本节课中,我们将学习如何在Ubuntu 22.04操作系统中安装网络模拟器NS-3.38。我们将从系统环境准备开始,逐步完成下载、解压、编译和测试的完整流程。
概述
安装NS-3需要完成几个关键步骤:首先更新系统并安装必要的编译工具和依赖包,然后下载NS-3.38源代码,接着解压并进入目录进行编译配置,最后通过运行示例程序来验证安装是否成功。整个过程大约需要10到15分钟。


第一步:安装系统依赖包
在全新的Ubuntu 22.04系统上,首先需要更新软件包列表并安装一些基础编译工具和库。这些是编译NS-3所必需的。
以下是需要执行的命令:
sudo apt update
sudo apt install build-essential autoconf automake libxmu-dev
执行这些命令后,系统将安装gcc、g++、make等编译工具以及autoconf、automake等自动化配置工具。
第二步:下载NS-3.38源代码
接下来,我们需要获取NS-3.38的源代码。访问NS-3官方网站(nsnam.org),找到并点击“Latest Release”链接,当前最新版本是NS-3.38。下载其压缩包(通常是.tar.bz2格式)到本地。
第三步:安装额外的可选包(推荐)
为了确保NS-3的所有功能(如网络动画NetAnim、数据包分析Wireshark等)都能正常工作,建议安装一系列额外的软件包。这可以避免后续因缺少依赖而出现的错误。
你可以从视频描述或NS-3官方文档中复制一个更全面的安装命令列表。一个示例如下:
sudo apt install g++ python3 python3-dev pkg-config sqlite3 cmake libxml2-dev libgtk-3-dev libboost-all-dev libgsl-dev libsqlite3-dev qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc libopenmpi-dev tcpdump wireshark
执行此命令会安装一整套开发库和工具,具体耗时取决于你的网络和电脑速度。
第四步:解压源代码包
下载完成后,需要解压源代码包。有两种常用方法:使用图形界面(GUI)或终端命令。为了便于新手理解,这里介绍图形界面方法。
- 找到下载的压缩文件(例如
ns-allinone-3.38.tar.bz2)。 - 右键点击该文件。
- 选择“提取到此处”或“Extract Here”。
- 建议将解压后的文件夹放在你的用户主目录(
/home/你的用户名/)下,这样便于后续查找和操作。
解压完成后,你会在主目录下看到一个名为 ns-allinone-3.38 的文件夹。
第五步:配置与编译NS-3
现在进入核心的编译环节。我们需要使用NS-3自带的构建脚本进行配置和编译。
- 打开终端。
- 使用
cd命令进入解压后的目录:cd ns-allinone-3.38 - 运行配置和编译命令。以下命令启用了示例程序和测试套件:
./build.py --enable-examples --enable-tests
这个编译过程会持续10到15分钟,期间终端会输出大量的编译信息。请耐心等待直到完成。
第六步:测试安装是否成功

编译完成后,我们需要验证NS-3是否被正确安装。最直接的方法是运行其自带的示例程序。
首先,我们可以运行一个简单的“Hello Simulator”程序:
./ns3 run hello-simulator
如果终端输出“Hello Simulator”字样,则表明核心安装成功。
此外,NS-3还提供了许多其他示例。你可以尝试运行 first 和 second 这两个基础示例:
./ns3 run first
./ns3 run second
成功运行这些示例并看到相应的网络模拟输出,即证明你的NS-3环境已经完全准备就绪,可以开始进行网络协议的仿真实验了。
总结

本节课中,我们一起学习了在Ubuntu 22.04系统上安装NS-3.38的完整步骤。我们首先安装了必要的系统依赖和编译工具,然后下载并解压了源代码。接着,我们通过运行 ./build.py 命令配置和编译了NS-3。最后,通过执行 hello-simulator、first 等示例程序,我们验证了安装的成功。现在,你已经拥有了一个可用的NS-3仿真环境,可以开始探索网络模拟的世界了。
37:NetSimluyzer - NS3的3D可视化工具 🖥️

在本节课中,我们将学习如何为NS3安装一个名为NetSimluyzer的软件。这是一个三维场景模拟器,可以可视化所有节点,并包含建筑物模型。无论是无线网络、有线网络还是混合网络,我们都可以使用它。NS3会生成一个JSON文件,NetSimluyzer可以通过这个JSON文件打开并展示模拟场景。
概述 📋
本教程将指导你完成在Ubuntu 22.04系统上,为NS3版本3.38安装NetSimluyzer版本1.0.7的全过程。NetSimluyzer是一个强大的软件,用于可视化NS3模拟的三维视图。我们将分步安装NS3核心、NetSimluyzer模块以及独立的NetSimluyzer可视化软件。
安装步骤 🛠️
第一步:安装NS3.38及NetSimluyzer模块
首先,我们需要安装NS3.38,并确保它能识别NetSimluyzer模块。这个过程较为复杂,因为NS3需要支持NetSimluyzer。
以下是安装所需的命令和步骤:
-
更新系统包列表:
sudo apt update在安装任何Linux软件前,建议首先更新包列表。
-
安装必要的依赖包:
复制并执行以下命令来安装NS3所需的一系列库。这个过程可能需要10到50分钟,具体取决于你的网络速度和系统性能。sudo apt install -y g++ python3 python3-dev pkg-config sqlite3 cmake python3-setuptools git qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc libopenmpi-dev autoconf cvs bzr unrar gdb valgrind uncrustify doxygen graphviz imagemagick texlive texlive-extra-utils texlive-latex-extra texlive-font-utils dvipng latexmk python3-sphinx dia gsl-bin libgsl-dev libgslcblas0 tcpdump sqlite sqlite3 libsqlite3-dev libxml2 libxml2-dev libgtk2.0-0 libgtk2.0-dev vtun lxc libc6-dev-i386 libclang-dev llvm-dev python3-pip libboost-all-dev libfreetype6-dev libpng-dev -
解压NS3安装包:
假设你已经下载了ns-allinone-3.38.tar.bz2文件到主目录。你可以通过终端命令或图形界面右键点击并选择“提取”来解压。tar xjf ns-allinone-3.38.tar.bz2 -
下载并集成NetSimluyzer模块:
进入NS3目录下的contrib文件夹,下载NetSimluyzer模块。cd ns-allinone-3.38/ns-3.38/contrib git clone https://github.com/GabrielJaguar/NetSimulyzer.git下载完成后,将其重命名为
netsimulyzer。mv NetSimulyzer netsimulyzer -
配置并编译NS3:
返回NS3主目录,运行配置脚本,启用示例和测试。cd ../.. ./ns-3.38/ns3 configure --enable-examples --enable-tests配置完成后,开始编译。这个过程可能需要10到20分钟,取决于你的电脑CPU和内存。
./ns-3.38/ns3 build
至此,NS3.38与NetSimluyzer模块的安装就完成了。接下来,我们安装独立的NetSimluyzer可视化软件。
第二步:安装独立的NetSimluyzer软件
现在,我们打开一个新的终端窗口,来安装用于打开JSON文件的三维可视化软件。
以下是安装步骤:
-
从GitHub克隆源码:
cd ~ git clone https://github.com/GabrielJaguar/NetSimulyzer.git -
创建并进入构建目录:
cd NetSimulyzer mkdir build cd build -
使用CMake配置项目:
cmake -DCMAKE_BUILD_TYPE=Release ..注意:避免使用并行编译选项(如
-j),它可能导致系统卡顿。 -
编译并安装软件:
cmake --build . sudo cmake --install .
现在,NetSimluyzer可视化软件也已安装成功。
验证安装 ✅
上一节我们完成了所有软件的安装,本节我们来验证安装是否成功。
验证NS3安装

运行以下命令检查NS3是否安装成功:
cd ns-allinone-3.38/ns-3.38
./ns3 run hello-simulator
如果命令成功执行并输出相关信息,则表明NS3安装正确。

验证NetSimluyzer模块
NetSimluyzer模块自带了一些示例,例如展示无人机、地面节点和智能手机的模拟。我们可以通过运行这些示例来测试。
以下是运行示例的步骤:
- 复制示例文件:
将NetSimluyzer模块中的示例源代码复制到NS3的scratch目录下,这是运行自定义脚本的地方。cp contrib/netsimulyzer/examples/*.cc scratch/

- 编译并运行一个示例:
我们以mobility-buildings-example.cc为例。在NS3主目录下执行:
程序运行后,会在当前目录生成一个JSON文件(例如./ns3 run scratch/mobility-buildings-examplenetsimulyzer-output.json)。这个文件包含了模拟的所有三维信息。

- 使用NetSimluyzer可视化:
打开NetSimluyzer软件,加载上一步生成的JSON文件。
在软件界面中,点击“Load”按钮,选择你的JSON文件。你将看到三维场景,其中包含编号的节点(如节点0、1、2、3)。在本示例中,节点2和3是地面无人机,在二维平面上移动。netsimulyzer

- 运行模拟:
在NetSimluyzer界面中,你可以将默认的10毫秒模拟时间增加到50毫秒,然后点击运行。你将看到节点根据NS3模拟的逻辑在三维空间中移动。

通过这种方式,任何使用NetSimluyzer API的NS3网络模拟都可以在这个三维可视化工具中打开和观察。
总结 🎯

本节课我们一起学习了如何为NS3安装和配置NetSimluyzer三维可视化工具。我们完成了三个主要部分:
- 安装了NS3.38并集成了NetSimluyzer模块。
- 安装了独立的NetSimluyzer可视化软件。
- 通过运行示例程序,验证了整个安装流程,并成功将NS3的模拟结果在三维视图中呈现出来。

现在,你可以利用这个强大的工具,更直观地分析和展示你的NS3网络模拟了。在下一个视频中,我们将深入讲解示例的源代码,帮助你理解如何编写自己的三维模拟场景。
38:在NS3中构建点对点网络 🖧
在本节课中,我们将学习如何在NS3网络模拟器中构建一个简单的点对点网络。我们将创建两个节点,通过一个具有特定带宽和延迟的物理链路连接,并模拟它们之间的数据包交换。课程内容包括网络动画演示、网络吞吐量计算以及使用图表工具进行结果可视化。
概述
我们将基于一个给定的实验问题来构建网络。该问题要求设计一个点对点网络,连接两个节点,链路数据速率为50 Mbps,延迟为5毫秒。其中一个节点作为服务器,另一个作为客户端,在20秒的总模拟时间内交换至少10个数据包。我们将分别测试最大数据包大小为1024字节和512字节的情况,并计算每个节点的吞吐量。
代码准备与解释
首先,我们需要一个基础代码文件。我们将使用NS3安装目录中自带的示例文件 first.cc。
以下是操作步骤:
- 找到
first.cc文件,其路径通常为ns-allinone-3.38/ns-3.38/examples/tutorial/first.cc。 - 将此文件复制到
ns-allinone-3.38/ns-3.38/scratch/目录下。 - 在文本编辑器中打开
scratch/first.cc文件进行修改。
接下来,我们将逐部分解释并修改源代码,以满足实验要求。
核心代码结构
代码始于必要的命名空间和头文件声明。
using namespace ns3;
主函数 main 是程序的入口点。我们首先设置时间分辨率为纳秒级。
Time::SetResolution (Time::NS);
创建节点与链路
我们使用 NodeContainer 类创建两个网络节点。
NodeContainer nodes;
nodes.Create (2);
接着,使用 PointToPointHelper 类来配置点对点链路属性。根据实验要求,我们将数据速率设置为50 Mbps,延迟设置为5毫秒。
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("50Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("5ms"));
然后,将配置好的链路安装在两个节点上,形成一个网络设备容器。
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
配置网络协议栈与IP地址
为了让节点能够进行网络通信,需要为它们安装互联网协议栈。
InternetStackHelper stack;
stack.Install (nodes);
之后,为链路上的设备分配IP地址。我们设置基础网络地址为 10.1.1.0。
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign (devices);
设置应用层通信
我们将使用UDP回声应用来模拟数据包交换。UdpEchoServerHelper 用于创建服务器端应用,并安装在第一个节点(n0)上,监听8080端口。
UdpEchoServerHelper echoServer (8080);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (0));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (20.0));
UdpEchoClientHelper 用于创建客户端应用,安装在第二个节点(n1)上。客户端将向服务器(10.1.1.1)发送10个数据包。
UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 8080);
echoClient.SetAttribute ("MaxPackets", UintegerValue (10));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); // 第一次模拟用1024
ApplicationContainer clientApps = echoClient.Install (nodes.Get (1));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (20.0));
启用数据追踪与动画
为了分析网络性能,我们需要启用ASCII数据包追踪功能。
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("1024.tr"));
为了直观展示网络动态,我们启用NetAnim动画接口。首先需要在文件开头包含头文件 #include "ns3/netanim-module.h"。
AnimationInterface anim ("p2p-animation.xml");
运行模拟与结果分析
代码修改完成后,即可编译并运行模拟。
编译与执行
在终端中,进入NS3目录并运行以下命令来执行第一次模拟(数据包大小1024字节)。
cd ns-allinone-3.38/ns-3.38
./ns3 run scratch/first.cc
模拟完成后,会生成追踪文件 1024.tr 和动画文件 p2p-animation.xml。
接着,修改 first.cc 文件中客户端数据包大小的属性为512,并更改追踪文件名。
echoClient.SetAttribute ("PacketSize", UintegerValue (512));
...
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("512.tr"));
再次运行模拟,生成 512.tr 追踪文件。
查看网络动画
使用NetAnim工具可以可视化数据包交换过程。
cd ns-allinone-3.38/netanim
./NetAnim
在NetAnim中打开生成的 p2p-animation.xml 文件,点击播放按钮即可观看模拟动画。
计算吞吐量

我们使用TraceMetrics工具来分析追踪文件中的吞吐量数据。

- 启动TraceMetrics。
cd ns-allinone-3.38/tracemetrics java -jar tracemetrics.jar - 在软件界面中,依次打开
1024.tr和512.tr文件。 - 执行分析后,在“吞吐量”结果中,记录下节点0和节点1的吞吐量值(单位:比特/秒)。


结果可视化
将得到的数据整理成表格,例如:
| 节点 | 1024字节包吞吐量 (bps) | 512字节包吞吐量 (bps) |
|---|---|---|
| n0 | 957.28 | 492.27 |
| n1 | 957.28 | 492.27 |
你可以使用任何熟悉的图表工具(如LibreOffice Calc, Microsoft Excel, Gnuplot)来绘制柱状图或折线图,对比不同数据包大小下的节点吞吐量。
以下是一个使用Gnuplot绘制简单折线图的脚本示例 plot.gp:
set terminal pdf
set output "throughput.pdf"
set title "吞吐量 vs. 数据包大小"
set xlabel "节点"
set ylabel "吞吐量 (bps)"
plot "data.txt" using 1:2 with linespoints title "1024 Bytes", \
"data.txt" using 1:3 with linespoints title "512 Bytes"
其中 data.txt 文件内容格式如下:
0 957.28 492.27
1 957.28 492.27
运行 gnuplot plot.gp 即可生成PDF格式的图表。
总结

本节课我们一起学习了在NS3中构建点对点网络的全过程。我们从修改基础示例代码开始,配置了链路的带宽和延迟参数,设置了UDP回声客户端和服务器应用,并启用了数据追踪和网络动画功能。通过运行两次模拟,我们获得了不同数据包大小下的网络性能数据。最后,利用TraceMetrics工具分析出节点的吞吐量,并使用图表工具将结果可视化。这个过程涵盖了NS3仿真的基本步骤:建模、模拟、分析和可视化,是进行更复杂网络研究的基础。
39:使用NS3实现路由信息协议(RIP)🔗
在本节课中,我们将学习一个名为路由信息协议(RIP)的协议。RIP属于距离向量路由协议类别。我们将通过NS3模拟,了解RIP的工作原理,特别是其三种关键机制:水平分割、毒性逆转以及无水平分割模式。
概述
距离向量路由意味着每个节点只将自己的路由表传输给最近的邻居。这些邻居再依次将它们的路由表传输给它们自己的邻居,以此类推,形成一个网络链。这样,网络中的所有节点都拥有不完整的信息,但整个网络作为一个整体,每个节点最终都能获得关于整个网络的完整信息。RIP就是距离向量路由协议的一个例子。
在本模拟中,我们将看到在NS3中如何实现RIP,并观察启用水平分割、无水平分割和毒性逆转这三种选项时,路由表如何变化,从而理解这三种机制在RIP协议中的作用。
核心概念解析
在深入模拟之前,我们先来理解RIP协议中涉及的三个核心概念。

无水平分割的问题
考虑一个由三个路由器R1、R2、R3组成的简单网络,它们彼此相连。假设网络10.0.1.0/16连接在R3上。
- 初始状态:R3将关于
10.0.1.0/16的路由更新发送给R2,R2再发送给R1。 - 链路故障:假设R2与R3之间的链路发生故障。
- 问题发生:在无水平分割模式下,R1仍然会向R2发送路由更新(声称可以通过R1到达
10.0.1.0/16),而R2在收到这个错误信息后,又会更新自己的路由表并可能将信息发回给R1(或R3,如果链路恢复),这可能导致R1和R2之间形成路由环路,数据包在两个路由器之间无限循环,无法到达真正目的地。
核心问题:无水平分割可能导致网络在发生故障后产生无限循环。
水平分割机制
水平分割是一种简单的改进机制。其规则是:从一个接口学到的路由,不会再从该接口通告出去。
沿用上面的例子:
当R2与R3之间的链路失效后,R1从R2(通过接口A)学到了通往10.0.1.0/16的路由。如果启用了水平分割,那么R1不会通过接口A(即朝向R2的方向)再次通告这条路由。这样就切断了错误信息反向传播的路径,从而避免了R1和R2之间形成环路。
毒性逆转机制
毒性逆转是水平分割的增强版,也称为“带毒性逆转的水平分割”。其规则是:从一个接口学到的路由,仍然会从该接口通告出去,但会将其度量(成本)设置为无穷大(在RIP中为16)。
再次使用上面的例子:
当R2与R3的链路失效后,R1会通过接口A向R2发送路由更新,告知通往10.0.1.0/16的路由,但度量值设为16。R2收到这个“毒化”的路由后,会立刻明白通过R1到达10.0.1.0/16是不可行的(成本无穷大),从而迅速将该路由标记为失效。这不仅能防止环路,还能加速整个网络的收敛速度,因为错误信息被明确标记并传播。
RIP中的无穷大:在RIP协议中,跳数16被定义为无穷大,表示网络不可达。任何度量值达到或超过16的路由都会被丢弃。
NS3模拟实例分析
现在,我们通过一个NS3模拟示例来具体观察这些机制。考虑以下网络拓扑:
SRC (源) --(1)-- A --(1)-- B --(1)-- DST (目的)
| | |
|(1) |(1) |(1)
C ----(10)--- D
(注:括号内数字为链路成本/跳数)
- 最优路径:初始时,SRC到DST的最短路径是
SRC -> A -> B -> DST,总成本为 1+1+1 = 3。 - 高成本链路:C和D之间的链路成本为10。
- 模拟事件:
- 模拟运行约3秒后,网络拓扑建立。
- 在40秒时,手动断开路由器B和D之间的链路(成本1的链路)。
- 链路断开导致原路径失效。RIP协议需要时间重新收敛。
- 大约在44秒(故障后4秒),网络通过发现新路径
SRC -> A -> C -> D -> DST恢复连通,但新路径成本为 1+1+10+1 = 13。
- 观察点:我们将通过打印路由表,查看在30秒、60秒、90秒时,各路由器(A, B, C, D)到达目标网络
10.0.6.0(DST)的路径和成本变化,特别是故障发生(40秒)前后。
NS3代码关键部分解析
以下是实现上述模拟逻辑的NS3代码关键步骤的说明:
- 启用日志:为了观察协议内部运作,需要启用相关组件的日志。
LogComponentEnable("Rip", LOG_LEVEL_INFO); LogComponentEnable("RipNg", LOG_LEVEL_INFO); LogComponentEnable("Ipv4Interface", LOG_LEVEL_INFO); // ... 其他组件(Icmpv4L4Protocol, Ipv4L3Protocol, ArpCache, Ping)的日志

- 设置水平分割策略:通过命令行参数或直接赋值,选择要测试的RIP变体。
// 定义策略枚举 std::string splitHorizon = "PoisonReverse"; // 可选项:"NoSplitHorizon", "SplitHorizon", "PoisonReverse" // 在代码中根据选择设置RIP助手的属性 if (splitHorizon == "NoSplitHorizon") { rip.SetAttribute("SplitHorizon", StringValue("NoSplitHorizon")); } else if (splitHorizon == "SplitHorizon") { rip.SetAttribute("SplitHorizon", StringValue("SplitHorizon")); } else { // PoisonReverse rip.SetAttribute("SplitHorizon", StringValue("PoisonReverse")); }


- 创建拓扑与安装协议:创建节点(SRC, DST, A, B, C, D),使用CSMA通道连接它们,并在路由器节点(A, B, C, D)上安装RIP协议栈。
// 创建节点 NodeContainer routers; routers.Create(4); // A, B, C, D NodeContainer nodes; nodes.Create(2); // SRC, DST // 连接节点(此处省略具体的PointToPoint或CSMA助手连接代码) // ... // 安装Internet协议栈和RIP路由 InternetStackHelper internet; RipHelper ripHelper; internet.SetRoutingHelper(ripHelper); // 在路由器上使用RIP internet.Install(routers); internet.Install(nodes); // 在终端节点上安装基础协议栈(通常用静态路由)

-
配置链路成本与故障:设置C-D链路的成本为10,并安排在40秒时触发B-D链路断开函数。
// 设置C-D链路接口的度量值(成本)为10 Ptr<Ipv4> ipv4C = routers.Get(2)->GetObject<Ipv4>(); // 节点C ipv4C->GetInterfaceMetric(3, 10); // 假设接口3连接D Ptr<Ipv4> ipv4D = routers.Get(3)->GetObject<Ipv4>(); // 节点D ipv4D->GetInterfaceMetric(1, 10); // 假设接口1连接C // 安排在40秒时断开B-D链路 Simulator::Schedule(Seconds(40.0), &TearDownLink, routerB, routerD, 3, 2); // TearDownLink 函数会将指定节点接口设置为down状态 -
生成流量与跟踪:在SRC和DST之间建立Ping应用以生成流量,并启用数据包捕获(如Wireshark格式)以便后期分析。
// 创建Ping应用 PingHelper ping(interfacesDst.GetAddress(1)); // Ping DST的地址 ping.SetAttribute("Verbose", BooleanValue(true)); ApplicationContainer p = ping.Install(nodes.Get(0)); // 安装在SRC上 p.Start(Seconds(1.0)); p.Stop(Seconds(110.0)); // 启用PCAP捕获 csma.EnablePcapAll("rip-simple-network");
模拟运行与结果分析
运行模拟后,我们可以从以下几个方面观察结果:

- 控制台输出(Ping结果):由于在40-44秒左右发生链路故障和收敛,Ping数据包会有一定丢失。输出可能显示类似“66% packets received”的信息,证实了网络中断的存在。
- 路由表打印:如果在代码中启用了
PrintRoutingTable,可以在30秒、60秒、90秒看到路由器A、B、C、D的路由表。- 30秒(故障前):所有路由器到
10.0.6.0的路径成本应为3(通过B)。 - 60秒(故障后,收敛前/收敛中):路由器B和D的相关路由可能显示为度量16(不可达),或者正在更新。路由器A和C的路由表可能开始显示经过C的新路径,但成本可能还不是最终值。
- 90秒(收敛后):所有路由器到
10.0.6.0的路径应更新为经过C的新路径,总成本显示为13(A->C->D->DST:1 + 10 + 1?注意实际跳数:SRC-A(1), A-C(1), C-D(10), D-DST(1) = 13)。在A的路由表中,下一跳可能是C(10.0.2.2),度量值为12(A->C->D->DST?这里需要根据具体IP分配计算)。关键点是成本从3增加到了12或13。
- 30秒(故障前):所有路由器到
- Wireshark分析:打开生成的
.pcap文件(例如rip-simple-network-3-2.pcap对应路由器C的第二个接口),观察RIP更新报文和数据报文(如ICMP Ping)。- 在40秒附近,可以看到RIP更新报文频繁交换(触发路由重新计算)。
- 在流量图上,可以看到在故障期间(约40-44秒),数据包流出现中断或延迟,之后流量恢复,但可能因为路径变长,端到端延迟有细微增加。
通过对比使用NoSplitHorizon、SplitHorizon和PoisonReverse三种模式下的收敛时间和路由表变化,可以直观地理解毒性逆转如何帮助网络更快地摆脱环路状态并稳定下来。
总结

本节课中,我们一起学习了距离向量路由协议的代表——RIP协议。我们首先从理论上分析了RIP协议中无水平分割可能引发的路由环路问题,进而介绍了水平分割及其增强版毒性逆转两种防环机制的工作原理。接着,我们通过一个具体的NS3模拟示例,演示了如何构建一个使用RIP的网络拓扑,如何设置链路成本、触发链路故障,并观察了网络在故障前后的收敛过程。通过分析代码配置、控制台输出的路由表变化以及Wireshark捕获的数据包,我们验证了RIP协议的行为以及不同防环机制的效果。本教程旨在帮助初学者理解RIP的基本概念及其在NS3中的实现方法。
40:NS3架构与入门指南 🚀
在本节课中,我们将要学习网络模拟器3(NS3)的基本架构、核心概念以及如何搭建和运行第一个模拟实验。课程内容涵盖从NS3的历史背景到其五大核心抽象,最后通过一个实际的移动自组织网络路由协议比较项目进行演示。
NS3架构简介 🏗️
首先,我们来介绍NS3的架构。NS2是1990年至2011年间使用的网络模拟器,而NS3则从2015年开始发展,现已趋于成熟。NS3主要支持C++和Python编程,用户可以根据自己的编程背景选择合适的语言进行开发。
NS3是一个离散事件模拟器,这意味着网络中的所有活动,如数据包发送、接收和结果绘制,都被建模为有限数量的事件。NS2和NS3都源自同一所大学,NS3继承并改进了NS2的许多模型。
环境搭建与准备 💻
为了简化安装过程,我们提供了一个预配置的Ubuntu虚拟机镜像。该镜像包含了NS3及其相关工具,避免了复杂的安装步骤。您可以在Windows或Linux系统上使用此虚拟机。
以下是环境搭建的步骤:



- 安装虚拟机软件:推荐使用Oracle VirtualBox或VMware Workstation Player。
- 下载并解压VM镜像:提供的镜像文件约为10.3 GB,解压后约为33 GB。建议将其放在非系统盘(如D盘)以节省空间。
- 配置并启动虚拟机:在虚拟机软件中创建新虚拟机,选择“使用现有虚拟硬盘”,并指向解压后的镜像文件。建议分配至少2 GB内存和2个CPU核心。
- 启动系统:虚拟机使用Ubuntu 22.04 LTS系统,用户名是
the,密码是123456。







NS3的核心工具 🛠️








NS3附带了一系列用于分析、可视化和调试模拟结果的工具。以下是主要工具列表:

- Wireshark:用于数据包捕获和分析。
- NetAnim:网络动画工具,用于可视化节点移动和数据包流。
- Trace Metrics:用于生成和分析跟踪文件。
- Flow Monitor:用于监控和管理数据包流。
- GNUplot:用于绘制图表和可视化结果。

NS3的五大核心抽象 🧩


理解NS3的架构,关键在于掌握其五大核心抽象概念。NS3完全采用面向对象编程,这些抽象是构成所有模拟的基础类。


- 节点:代表网络中的计算设备,如计算机或服务器。在代码中通常使用
NodeContainer来创建和管理节点。NodeContainer nodes;nodes.Create(50); // 创建50个节点


- 信道:代表节点之间的通信路径。它可以是有线信道(如以太网)或无线信道(如Wi-Fi)。
PointToPointHelper p2p; // 点对点信道CsmaHelper csma; // CSMA(载波侦听多路访问)信道YansWifiChannelHelper wifiChannel; // Wi-Fi信道

- 应用:代表在节点上运行的程序,如客户端或服务器。它定义了网络流量的生成和消费。
UdpEchoServerHelper echoServer(9); // UDP回声服务器UdpEchoClientHelper echoClient(serverAddress, 9); // UDP回声客户端


-
网络设备:代表节点的网络接口卡(NIC),是软件与硬件的结合体。它负责处理如IP地址分配、子网掩码等网络层功能。
NetDeviceContainer devices;devices = wifi.Install(wifiPhy, wifiMac, nodes); // 为节点安装Wi-Fi网络设备
-
拓扑辅助类:这是一组帮助类,用于简化复杂协议的配置,如路由协议(AODV, DSR)、移动性模型等。它们不属于上述四类,但对于构建完整拓扑至关重要。
AodvHelper aodv; // AODV路由协议辅助类MobilityHelper mobility; // 移动性模型辅助类
实战演练:移动自组织网络路由协议比较 📡




上一节我们介绍了NS3的理论基础,本节中我们来看看如何运行一个完整的模拟项目。我们将使用NS3自带的示例程序,比较四种无线自组织网络路由协议:OLSR、AODV、DSDV和DSR。
项目概述
该模拟在300m x 1500m的区域内放置50个移动节点,节点以随机路点模型移动,速度最大为20m/s。模拟运行200秒,其中前50秒为网络启动时间。有10对源-目的节点使用UDP以2.048 kbps的速率发送数据。我们将比较各协议的接收速率和数据包接收数。
运行步骤
以下是运行该比较项目的具体步骤:



- 定位并复制示例文件:示例文件通常位于
ns-allinone-3.38/ns-3.38/examples/routing/目录下,名为manet-routing-compare.cc。需要将其复制到scratch/目录下才能执行。cp ns-allinone-3.38/ns-3.38/examples/routing/manet-routing-compare.cc ns-allinone-3.38/ns-3.38/scratch/






- 运行模拟(以AODV协议为例):进入NS3主目录,使用
./ns3 run命令执行脚本,并通过命令行参数指定输出文件名和协议编号。cd ns-allinone-3.38/ns-3.38./ns3 run "scratch/manet-routing-compare --CSVfileName=AODV.csv --protocol=2"- 协议编号:1=OLSR, 2=AODV, 3=DSDV, 4=DSR








- 为所有协议生成数据:依次运行四次命令,为四种协议生成各自的CSV结果文件。
- 使用GNUplot绘制对比图:编写一个GNUplot脚本(如
protocol.plot),读取四个CSV文件中的“接收速率”和“接收包数”数据,并生成对比图表。gnuplot protocol.plot- 生成的PDF图表将直观展示四种协议的性能差异。
结果分析与扩展实验


通过生成的图表,我们可以分析哪种协议在特定场景下(如节点密度、移动速度、发射功率)表现更优。例如,实验可能显示AODV协议在接收速率上优于DSDV。








您可以轻松修改源代码中的参数进行扩展实验,例如:
- 改变节点数量(30, 80, 100)。
- 调整节点移动速度。
- 改变发射功率(如从1.5 dBm改为7.5 dBm),然后重新运行比较,观察网络性能如何随功率变化。

















总结 🎯





本节课中我们一起学习了网络模拟器NS3的核心架构,包括其五大抽象概念:节点、信道、应用、网络设备和拓扑辅助类。我们完成了从搭建预配置的虚拟机环境,到运行一个完整的移动自组织网络路由协议性能比较项目的全过程。通过这个实战项目,您应该已经掌握了如何查找、运行、修改NS3示例代码,并使用工具分析结果。这是进行更深入网络研究的基础。
41:在Ubuntu 22.04中安装ns-3.41 🖥️
在本节课中,我们将学习如何在Ubuntu 22.04操作系统中安装网络模拟器ns-3,具体版本为ns-3.41。我们将从下载软件包开始,逐步完成所有必要的系统更新、依赖库安装以及最终的编译和测试过程。
概述与准备工作
首先,我们需要下载ns-3.41的安装包。我们将访问官方网站 nsnam.org 来获取最新版本。本教程的步骤同样适用于ns-3.40版本。
下载完成后,我们将把软件包存储在本地文件夹中并进行解压。
第一步:更新系统与安装依赖

在开始安装ns-3之前,必须确保系统已更新,并安装所有必要的依赖软件包。以下是需要执行的命令。
打开终端,输入以下命令来更新系统软件包列表:
sudo apt update
更新完成后,我们将安装一系列运行ns-3所必需的软件包和第三方库。一次性安装所有依赖可以避免未来可能出现的兼容性问题。

以下是需要复制并粘贴到终端中执行的完整安装命令:
sudo apt install -y gcc g++ python3 python3-dev pkg-config sqlite3 cmake build-essential libgtk-3-dev libboost-all-dev libgsl-dev libxml2-dev libreadline-dev valgrind gdb qt5-default mercurial git ca-certificates
该命令的执行时间取决于您的网络速度。所有软件包安装完成后,终端会显示相应的完成提示。
第二步:准备ns-3安装包
假设我们已经从网站下载了 ns-allinone-3.41.tar.bz2 文件,它通常位于“下载”文件夹中。
为了操作方便,建议将此文件移动到用户的主目录(/home/你的用户名/)。然后,在该文件上点击右键,选择“提取到此处”选项进行解压。
解压完成后,您将在主目录中看到一个名为 ns-allinone-3.41 的新文件夹。这就是我们将要安装的ns-3软件目录。
第三步:编译与安装ns-3
现在,我们需要在终端中编译ns-3的源代码。请打开一个新的终端窗口,新终端默认会指向您的主目录。
首先,使用 cd 命令进入解压后的ns-3目录:
cd ns-allinone-3.41
进入目录后,执行以下配置和编译命令。此命令启用了示例程序和测试套件:
./build.py --enable-examples --enable-tests


请注意:命令中的单词之间不应有多余的空格。
此编译过程可能需要大约20分钟,具体时间取决于您的计算机性能。在我的测试中,大约花了15分钟完成。
第四步:验证安装
编译安装完成后,我们需要验证ns-3是否已正确安装并可以运行。我们将运行两个内置的示例程序进行测试。
首先,确保您仍在 ns-allinone-3.41 目录中。然后运行第一个示例:
./ns3 run first
接着,运行第二个示例:
./ns3 run second
如果安装成功,您将在终端中看到相应的输出结果。例如,程序可能会输出“hello simulator”等信息,这表明ns-3模拟器已成功安装并可以正常工作。
总结

本节课中,我们一起完成了在Ubuntu 22.04系统上安装ns-3.41的全过程。我们学习了如何更新系统、安装必要的依赖库、解压软件包、编译源代码,并通过运行示例程序来验证安装是否成功。现在,您已经拥有了一个可以正常工作的ns-3网络模拟环境,可以开始进行后续的网络协议仿真实验了。

浙公网安备 33010602011771号