无线自组织网络ns-3仿真实验

实验概述

本次实验基于ns-3WiFi模块的AdHoc模式仿真一个无线自组织网络。一方面,通过仿真不同路由算法,了解无线自组织网络路由协议的主要类型及其特点;另一方面,学习如何为自组织网络的无线节点设置位置和移动性模型,以及用NetAnim工具对仿真过程动画可视化。

实验目标

  • 熟悉无线自组织网络的路由算法类型;
  • 掌握ns-3中自组织网络路由协议的设置方法;
  • 掌握ns-3移动性及节点位置模型的设置方法;
  • 了解ns-3仿真的动画可视化工具NetAnim。

预备知识

无线自组织网络(Mobile Ad hoc Networks, MANET)是一种分布式的无线网络,最早起源于美国国防高级研究计划局(DARPA)于1970开展研究的分组无线电网络(Packet
Radio Network,PRNET)。Ad hoc 源自拉丁文,意为临时的、特设的、自发组织的。MANET通过无线节点之间直接连接构成动态网络,每个节点既是终端,也作为路由节点转发数据包给其他节点。相对应地,日常使用的WiFi无线网络则是以接入点(AP)为中心的基础架构(infrastructure)模式。这种模式下AP是无线局域网内唯一具有路由功能的节点,终端之间的通信均通过AP转发。由于可以不依赖于基础设施网络而自由地、即时地组网,MANET 在军事、应急救援、车联网、无人机通信等场景应用广泛。具体来说,车联网又称为VANET(Vehicular Ad hoc Network),无人机网络则称为 FANET(Flying Ad hoc Network)。

在去中心化的背景下,由于节点移动性导致连接频繁断开或条件变化,数据包的路由是MANET 面临的主要技术挑战之一。按照路由表的建立方式,MANET 路由算法大致可划分为平面式路由、分层路由、地理位置辅助的路由等三类。平面式路由中网络节点处于“同等地位”,通过交换协议消息建立路由表;分层路由将节点划分为不同层次,仅同层次节点间进行交换,再由高层节点服务低层节点;地理位置辅助的路由则主要用于节点可获知其他节点位置信息的场景。

平面式路由是基础的 MANET 路由方式,可进一步分为主动式(proactive)和被动式(reactive)两种。前者节点定期交互路由信息,使得各节点始终维持可用的路由表,故
又称表驱动式(Table-Driven)路由。后者则只在节点需要发送数据时,即时地通过泛洪方式(flooding)寻找路径,故又称按需(On-Demand)路由。主动式路由算法的典型代表包括OLSR(Optimized Link-State Routing)、DSDV(Destination Sequence Distance Vector)等,被动式的典型代表则是AODV(AdhocOn-demand Distance Vector)、DSR(Dynamic Source Routing)等。需要指出的是,MANET 中路由协议的消息分组与应用层的数据分组一样,均通过随机接入方式竞争传输机会。

MANET的随机接入和物理层包含在IEEE802.11系列协议之中。WiFi对应的802.11a、802.11n、802.11ac、802.11ax 等均支持开启 ad hoc 模式。

实验内容

本次实验使用提供的 manet.cc脚本,仿真由一组WiFi节点构成的网格状MANET。创建AdHoc 模式的无线网络与常规WiFi网络大致相同,区别主要在设置Mac对象的类型为 AdhocWifiMac. 这里使用Friis 自由空间路损模型以仿真室外空旷环境的信号传播衰减。相对地,实验五中则使用了 YansWifiChannelHelper::Default(),对应对数距离(Log-Distance)路损模型,一般用于仿真室内和散射体密集环境。本实验中节点的发送功率设为23dBm(即200mW)。

节点位置及移动性模型是MANET的核心要素。这里使用 GridPositionAllocator将节点初始置于网格结点,进而设置 RandomWalk2dMobilityModel 移动性模型,使仿真中节点在二维平面上随机游走。

问题 6.1

查阅文档,指出ns-3 还有哪些自带的节点位置分配和移动性模型?假设要仿真两个并行车道上的节点向一个方向同时运动,可以分别使用什么位置分配和移动性模型?
ns-3 提供了多种节点位置分配和移动性模型,以支持不同的网络模拟需求。下面列出了一些常用的位置分配和移动性模型:

节点位置分配器 (Position Allocators)

  1. 随机矩形位置分配器 (RandomRectanglePositionAllocator): 在一个指定的矩形区域内随机分配位置。
  2. 随机盘面位置分配器 (RandomDiscPositionAllocator): 在一个指定的圆盘(盘面)内随机分配位置。
  3. 网格位置分配器 (GridPositionAllocator): 将节点在一个网格中均匀分布。
  4. 列表位置分配器 (ListPositionAllocator): 允许用户提供一个节点位置的列表。
  5. UniformDiscPositionAllocator: 在一个圆形区域内均匀分配位置。

移动性模型 (Mobility Models)

  1. 恒定位置模型 (ConstantPositionMobilityModel): 节点位置固定不变​​。
  2. 随机游走模型 (RandomWalk2dMobilityModel): 节点在二维平面上进行随机游走。
  3. 随机方向模型 (RandomDirection2dMobilityModel): 节点随机选择一个方向和速度,移动一段时间后改变方向。
  4. 恒定速度模型 (ConstantVelocityMobilityModel): 节点以恒定的速度沿直线移动。
  5. 恒定加速度模型 (ConstantAccelerationMobilityModel): 在节点的移动中引入加速度。

仿真场景:两个并行车道上的节点向一个方向同时运动

对于模拟两个并行车道上的节点向一个方向同时运动的场景, 推荐使用以下模型:

  1. 位置分配器: 使用 GridPositionAllocatorListPositionAllocator。这两种分配器可以帮助您精确放置车道上的每个节点。 GridPositionAllocator 可以在一行中均匀排列多个节点,而 ListPositionAllocator 允许您手动指定每个节点的初始位置。

  2. 移动性模型: 使用 ConstantVelocityMobilityModel。这个模型可以让所有节点以恒定的速度直线移动,适合模拟车辆在高速公路上的行驶。

问题6.2

在设置了物理层,Mac层,移动性模型等要素后,即可使用相应Helper 类为节点配置路由协议,例如AODV协议:

 InternetStackHelper stack;
 AodvHelper aodv;
 stack.SetRoutingHelper (aodv);
 stack.Install (stas);

分别执行下列命令,仿真AODV和OLSR作为MANET路由协议时的传输:

./ns3 run "manet --nStaEachRow=4 --squareLength=2000 --sendRate=100Kbps --simDuration=500 --routingProt=AODV --randomWalk=true" &> aodv-randomWalk.log

./ns3 run "manet --nStaEachRow=4 --squareLength=2000 --sendRate=100Kbps --simDuration=500 --routingProt=OLSR --randomWalk=true" &> olsr-randomWalk.log

结合仿真脚本,说明上述命令和参数的含义

mannet.cc中,各参数的含义

  CommandLine cmd (__FILE__);
  cmd.AddValue ("verbose", "Print trace information if true", g_verbose);
  cmd.AddValue ("nStaEachRow", "Number of stations in each row", nStaEachRow);
  cmd.AddValue ("sendRate", "Packet rate from sender", sendRate);
  cmd.AddValue ("simDuration", "Duration of data logging phase (s)", simDuration);
  cmd.AddValue ("squareLength", "Side length of square area of nodes", squareLength);
  cmd.AddValue ("routingProt", "Routing protocol for MANET, AODV or OLSR", routingProt);
  cmd.AddValue ("randomWalk", "Enable random walk of nodes in the area", randomWalk);
  cmd.Parse (argc, argv);

上述命令用于运行ns-3网络仿真工具中的一个特定仿真命令,并将输出重定向到一个日志文件。具体解释如下:

命令结构

./ns3 run "manet --nStaEachRow=4 --squareLength=2000 --sendRate=100Kbps --simDuration=500 --routingProt=AODV --randomWalk=true" &> aodv-randomWalk.log

各部分含义

  1. ./ns3 run "manet ... ":

    • ./ns3:这是ns-3仿真工具的执行文件(通常是一个可执行的脚本或二进制文件)。
    • run:运行指定的仿真脚本或程序。
    • "manet ...":这是传递给./ns3的具体仿真参数。
  2. "manet ... ":

    • manet:指定要运行的仿真场景或脚本的名称,这里指的是提供的源代码一个移动自组织网络(Mobile Ad hoc NETwork, MANET)的仿真。
    • 其后的参数是传递给该仿真场景或脚本的具体仿真配置。
  3. 各个参数

    • --nStaEachRow=4:仿真场景中每行有4个节点(STA,站点)。
    • --squareLength=2000:仿真区域为2000单位长度的方形区域(2000m x 2000m)。
    • --sendRate=100Kbps:节点之间的发送速率为100 Kbps。
    • --simDuration=500:仿真时长为500单位时间(s)。
    • --routingProt=AODV:使用AODV(Ad hoc On-Demand Distance Vector)路由协议。
    • --randomWalk=true:启用随机行走(Random Walk)模型,节点将随机移动。
  4. &> aodv-randomWalk.log

    • &>:这是一个shell重定向运算符,表示将标准输出和标准错误都重定向到指定文件。
    • aodv-randomWalk.log:记录仿真输出的日志文件的名称。

这条命令的总体作用是运行一个ns-3仿真,仿真一个使用AODV路由协议、随机行走的移动自组织网络,网络中每行有4个节点,仿真区域是2000x2000单位面积,发送速率为100 Kbps,仿真持续500秒。仿真过程中产生的输出信息将被重定向并保存到aodv-randomWalk.log文件中。

问题 6.3

仿真脚本调用了PrintRouteingTableAllAt函数在2s,5s,90,时将各节点的路由表打印在了文件中。请阅读仿真脚本确定相应文件名,并分析AODV在2s时的路由表,指出从节点0(IP地址10.0.0.1)到节点15(IP地址10.0.0.16)的路径。

通过阅读仿真脚本,文件名为"aodv.at2.routes"

相应的路由表如下

Node: 0; Time: +2s, Local time: +2s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.16       10.0.0.5        10.0.0.1        UP              +2.9s           6

Node: 4; Time: +2s, Local time: +2s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.16       10.0.0.6        10.0.0.5        UP              +2.9s           5


Node: 5; Time: +2s, Local time: +2s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.16       10.0.0.7        10.0.0.6        UP              +2.9s           4

Node: 6; Time: +2s, Local time: +2s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.16       10.0.0.11       10.0.0.7        UP              +2.9s           3

Node: 10; Time: +2s, Local time: +2s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.16       10.0.0.15       10.0.0.11       UP              +2.9s           2

Node: 14; Time: +2s, Local time: +2s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.16       10.0.0.16       10.0.0.15       UP              +2.9s           1

截取了关于10.0.0.1和10.0.0.16的路由表信息

路由表分析

  1. Node:0设备的路由表,去往10.0.0.16的网关是10.0.0.5,经过本设备的接口10.0.0.1,跳数为6跳,意味着还需要经过6次转发才能达到10.0.0.16设备;
  2. 根据Node:0设备路由表的信息,找出网关为10.0.0.5的设备Node:4。此时查看该设备的路由表,确定转发路径的下一台设备10.0.0.6即(Node:5);
  3. 重复上述步骤,可以得出从节点0(IP地址10.0.0.1)到节点15(IP地址10.0.0.16)的路径

AODV是一种按需路由协议,通过路由请求(RREQ)和路由回复(RREP)消息发现和维护路由。只有当源节点需要发送数据时才会启动路由发现过程。因此,路由表内容是动态生成的,基于实际需求。

AODV_2s.png

由NetAnim可视化工具可以看出该路径具体信息

路径为:

Node:0 $\rightarrow$ Node:4 $\rightarrow$ Node:5 $\rightarrow$ Node:6 $\rightarrow$ Node:10 $\rightarrow$ Node:14 $\rightarrow$ Node:15

10.0.0.1 $\rightarrow$ 10.0.0.5 $\rightarrow$ 10.0.0.6 $\rightarrow$ 10.0.0.7 $\rightarrow$ 10.0.0.11 $\rightarrow$ 10.0.0.15 $\rightarrow$ 10.0.0.16

问题 6.4

试推测为什么问题6.2中OLSR在2s时路由表为空?提示:这与 OLSR 的主动式路由方式有关。请查阅资料,了解OLSR的基本特点。

OLSR(优化链路状态路由协议)是一种主动式路由协议,意味着它通过周期性地交换控制信息(如HELLO消息和TC消息)来维护网络中的路由信息。然而,在OLSR启动后的初始阶段,尤其是在网络初次启动或节点刚加入网络时,可能出现路由表暂时为空的情况。以下是推测OLSR在2秒时路由表为空的几个可能原因:

  1. 建立全网拓扑的初始延迟
  • 信息传播延迟:当OLSR协议在2秒钟时间内启动时,可能节点之间的HELLO消息和TC消息尚未完全传播和处理完毕。HELLO消息用于发现邻居节点并进行MPR选择,而TC消息用于传播全网的拓扑信息。这需要一定时间才能在整个网络中传播和处理完毕。
  • 初始拓扑构建:在初期,节点需要收集足够的邻居信息和拓扑信息才能计算出完整的路由表。在这2秒钟内,尚未完成所有信息的收集和计算。
  1. 定时更新机制
  • 定时更新:OLSR协议中的消息传递(如HELLO消息和TC消息)是周期性进行的。默认情况下,这些消息的发送间隔可能是多秒钟(例如2秒到10秒)。如果节点在最初2秒内未接收到足够的邻居或拓扑信息,路由表将暂时为空。
  • 定时器配置:每个节点通常配置了定时器来控制信息发送的频率。例如,HELLO消息的发送间隔和TC消息的发送间隔。如果这些定时器尚未触发,节点还未获取新的拓扑信息来更新路由表。
  1. MPR选择和传播延时
  • 多点中继选择:OLSR通过MPR减少控制消息泛滥。在初期,通过HELLO消息选择MPR的过程需要一定时间。如果MPR选择过程尚未完成,则无法有效进行TC消息的传播,导致路由表暂时无法更新。
  • MPR传播:MPR节点需要将拓扑变化信息广播给其他节点。这一过程同样需要时间。如果2秒内还未完成MPR的消息转发,路由表可能为空。
  1. 网络环境和规模
  • 节点数目和密度:在一个大规模或高密度的网络中,信息传播的延迟可能更大,导致在短时间内路由表无法及时更新。
  • 节点移动性:如果节点在2秒内快速移动,也可能导致邻居信息频繁变化,进一步增加路由表更新的复杂性和延迟。

总结
OLSR在2秒时路由表为空,主要原因可能是由于协议的周期性消息更新和初始拓扑构建需要时间。当网络刚启动或节点刚加入网络时,节点可能未能在2秒内收集到足够的邻居信息和拓扑信息来计算和更新路由表。这是OLSR作为主动式路由协议的一种典型动态行为特征。随着时间的推移和控制信息的传播,路由表会逐渐被填充并保持更新。

通过阅读 OLSR RFC 3626 '18. Proposed Values for Constans'

18.2 'Emission Intervals'
HELLO_INTERVAL = 2 seconds

      REFRESH_INTERVAL      = 2 seconds

      TC_INTERVAL           = 5 seconds

      MID_INTERVAL          = TC_INTERVAL

      HNA_INTERVAL          = TC_INTERVAL

OLSR在2秒时路由表为空,主要原因可能是由于协议的周期性消息更新需要时间。

问题 6.5

分别分析AODV和OLSR在90s时的路由表,指出从节点0到节点15的路径。AODV的路由路径与2s时是否相同?原因可能是说明?AODV与OLSR在90s时的路由路径是否相同?原因可能是什么?

AODV在90s时的路由表

Node: 0; Time: +90s, Local time: +90s, AODV Routing table

AODV Routing table
Destination     Gateway         Interface       Flag            Expire          Hops
10.0.0.2        10.0.0.2        10.0.0.1        UP              +13s            1
10.0.0.3        10.0.0.3        10.0.0.1        UP              +9s             1
10.0.0.5        10.0.0.5        10.0.0.1        UP              +5.5s           1
10.0.0.6        10.0.0.6        10.0.0.1        UP              +11s            1
10.0.0.9        10.0.0.9        10.0.0.1        DOWN            +13s            1
10.0.0.13       10.0.0.13       10.0.0.1        UP              +5.5s           1
10.0.0.16       102.102.102.102 102.102.102.102 IN_SEARCH       +5.3s           3
10.255.255.255  10.255.255.255  10.0.0.1        UP              +9.2e+09s       1
127.0.0.1       127.0.0.1       127.0.0.1       UP              +9.2e+09s       1

虽然node 0的AODV路由表中有目的地址为10.0.0.16的路由表项,但该路由表项状态为IN_SEARCH,表明此时10.0.0.16为目的地址的路径已失效,需要重新建立。Hops为3,表面在3跳内,无法直接到达10.0.0.16即node 15设备。

OLSR在90s时的路由表

Node: 0, Time: +90s, Local time: +90s, OLSR Routing table
Destination     NextHop         Interface       Distance
10.0.0.2        10.0.0.2        1               1
10.0.0.3        10.0.0.3        1               1
10.0.0.4        10.0.0.13       1               3
10.0.0.5        10.0.0.5        1               1
10.0.0.6        10.0.0.6        1               1
10.0.0.7        10.0.0.13       1               4
10.0.0.8        10.0.0.13       1               4
10.0.0.9        10.0.0.9        1               1
10.0.0.10       10.0.0.9        1               2
10.0.0.11       10.0.0.13       1               2
10.0.0.12       10.0.0.13       1               3
10.0.0.13       10.0.0.13       1               1

在node 0时OLSR路由表中没有10.0.0.16的路由表项,表明目前没有达到10.0.0.16的路径

AODV的路由路径与2s时是否相同?

AODV的路由在90s时与2s时不相同,可能原因是随着各个节点的移动,网络topo发生变化,2s时构建的路由表不再适合90s后的链路状态。故此90s的路由与2s的路由不相同。

AODV与OLSR在90s时的路由路径是否相同?原因可能是什么?

通过观察AODV和OLSR的路由表,可以看出,此时路由路径不同,AODV并没有去向10.0.0.11,10.0.0.12的路由。造成这样的原因可能是AODV和OLSR构建路由的周期和频率不同,可以看出AODV不能够及时指导topo的变化。

90sAODV.png

通过90s时的NetAnim 截图可以看出,此时node 15(10.0.0.16)已经随机移动到比较远的位置,导致90s时无法得知到10.0.0.16路径的原因可能时因为node 15较远,无法与其他节点建立联系

问题 6.6

处理问题6.2输出的 aodv-randomWalk.log 和 olsr-randomWalk.log 日志。绘出实时吞吐量(累计已收到的字节数除以当前时间)随时间变化的曲线。试指出AODV和OLSR 吞吐量的差异及其原因。

Number of Stations: 16 sendRate: 100Kbps Throughput: 0.0427968 Mb/s(AODV)
Number of Stations: 16 sendRate: 100Kbps Throughput: 0.018048 Mb/s (OLSR)

import matplotlib.pyplot as plt
import numpy as np
# 从 log 文件中读取数据
data = []
with open("aodv-randomWalk.log", "r") as file:
    for line in file:
        if "[SinkRx]" in line:
            parts = line.strip().split()
            time = float(parts[1])
            #print(time)
            sent_data = int(parts[3])
            #print(sent_data)
            data.append([time, sent_data])

# 提取时间和已发送数据量
time = [item[0] for item in data]
sent_data = [item[1] for item in data]
#time = np.diff(time)
# 计算实时吞吐量(已发送数据量除以时间)
#throughput = [sent_data[i] / (time[i]) if time[i] != 0 else 0 for i in range(len(time))]
throughput = [sum(sent_data[:i+1]) / time[i] if time[i] != 0 else 0 for i in range(len(time))]

# 绘制实时吞吐量曲线图
plt.plot(time, throughput)
plt.xlabel('Time (s)')
plt.ylabel('Throughput')
plt.title('olsr Real-time Throughput vs. Time')
plt.grid(True)
plt.show()


import matplotlib.pyplot as plt
import numpy as np
# 从 log 文件中读取数据
data = []
with open("olsr-randomWalk.log", "r") as file:
    for line in file:
        if "[SinkRx]" in line:
            parts = line.strip().split()
            time = float(parts[1])
            #print(time)
            sent_data = int(parts[3])
            #print(sent_data)
            data.append([time, sent_data])

# 提取时间和已发送数据量
time = [item[0] for item in data]
sent_data = [item[1] for item in data]
#time = np.diff(time)
# 计算实时吞吐量(已发送数据量除以时间)
#throughput = [sent_data[i] / (time[i]) if time[i] != 0 else 0 for i in range(len(time))]
throughput = [sum(sent_data[:i+1]) / time[i] if time[i] != 0 else 0 for i in range(len(time))]

# 绘制实时吞吐量曲线图
plt.plot(time, throughput)
plt.xlabel('Time (s)')
plt.ylabel('Throughput')
plt.title('olsr Real-time Throughput vs. Time')
plt.grid(True)
plt.show()

import matplotlib.pyplot as plt
import numpy as np

# 从 log 文件中读取数据
def read_log(filename):
    data = []
    with open(filename, "r") as file:
        for line in file:
            if "[SinkRx]" in line:
                parts = line.strip().split()
                time = float(parts[1])
                sent_data = int(parts[3])
                data.append([time, sent_data])
    return data

# 计算实时吞吐量(将字节转换为 MB)
def calculate_throughput(time, sent_data):
    return [sum(sent_data[:i+1]) / (1024**2) / time[i] if time[i] != 0 else 0 for i in range(len(time))]

# 读取 aodv-randomWalk.log 数据
data_aodv = read_log("aodv-randomWalk.log")
time_aodv = [item[0] for item in data_aodv]
sent_data_aodv = [item[1] for item in data_aodv]
throughput_aodv = calculate_throughput(time_aodv, sent_data_aodv)

# 读取 olsr-randomWalk.log 数据
data_olsr = read_log("olsr-randomWalk.log")
time_olsr = [item[0] for item in data_olsr]
sent_data_olsr = [item[1] for item in data_olsr]
throughput_olsr = calculate_throughput(time_olsr, sent_data_olsr)

# 绘制实时吞吐量曲线图
plt.plot(time_aodv, throughput_aodv, label='AODV')
plt.plot(time_olsr, throughput_olsr, label='OLSR')
plt.xlabel('Time (s)')
plt.ylabel('Throughput (MB/s)')
plt.title('Real-time Throughput vs. Time')
plt.legend()
plt.grid(True)
plt.show()

import matplotlib.pyplot as plt
import numpy as np

# 从 log 文件中读取数据
def read_log(filename):
    data = []
    with open(filename, "r") as file:
        for line in file:
            if "[SinkRx]" in line:
                parts = line.strip().split()
                time = float(parts[1])
                sent_data = int(parts[3])
                data.append([time, sent_data])
    return data

# 计算实时吞吐量(将字节转换为 MB)
def calculate_throughput(time, sent_data):
    return [sum(sent_data[:i+1])*8 / (1e6) / time[i] if time[i] != 0 else 0 for i in range(len(time))]

# 计算平均吞吐量(将字节转换为 MB)
def calculate_average_throughput(sent_data, total_time):
    total_data_mb = sum(sent_data)*8 / (1e6)
    print(total_data_mb)
    return total_data_mb / total_time if total_time != 0 else 0

# 读取 aodv-randomWalk.log 数据
data_aodv = read_log("aodv-randomWalk.log")
time_aodv = [item[0] for item in data_aodv]
sent_data_aodv = [item[1] for item in data_aodv]
throughput_aodv = calculate_throughput(time_aodv, sent_data_aodv)
average_throughput_aodv = calculate_average_throughput(sent_data_aodv, time_aodv[-1])

# 读取 olsr-randomWalk.log 数据
data_olsr = read_log("olsr-randomWalk.log")
time_olsr = [item[0] for item in data_olsr]
sent_data_olsr = [item[1] for item in data_olsr]
throughput_olsr = calculate_throughput(time_olsr, sent_data_olsr)
average_throughput_olsr = calculate_average_throughput(sent_data_olsr, time_olsr[-1])

# 绘制实时吞吐量曲线图
plt.plot(time_aodv, throughput_aodv, label='AODV Throughput')
plt.plot(time_olsr, throughput_olsr, label='OLSR Throughput')

# 添加平均吞吐量线
plt.axhline(y=average_throughput_aodv, color='blue', linestyle='--', label=f'AODV Average Throughput: {average_throughput_aodv:.4f} MB/s')
plt.axhline(y=average_throughput_olsr, color='orange', linestyle='--', label=f'OLSR Average Throughput: {average_throughput_olsr:.4f} MB/s')

plt.xlabel('Time (s)')
plt.ylabel('Throughput (MB/s)')
plt.title('Real-time Throughput vs. Time')
plt.legend()
plt.grid(True)
plt.show()

21.3984
9.024

AODV和OLSR实时吞吐量分析
AODV

  • AODV根据图一可以看出,吞吐量曲线波动较小;
  • AODV 在数据包传输过程中逐跳地维护路由表。因为是按需式路由,所以路由表的更新频率相对较低。

OLSR

  • OLSR根据图一可以看出,吞吐量曲线波动较明显;
  • OLSR 周期性地交换链路状态信息以更新路由表。这种频繁的链路状态信息交换可能会增加网络控制开销,但使得路由表始终保持最新。
posted @   jiuzhao14  阅读(602)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示