AODV移动自组网仿真实战:NS2建模、脚本与性能分析

发布时间:2026/10/4 22:47:01
AODV移动自组网仿真实战:NS2建模、脚本与性能分析 简介移动自组网仿真资源面向无线网络研究者与AODV协议学习者聚焦Ad Hoc网络中按需距离矢量路由的实现与验证。资源包共3个文件均为C/C头文件压缩后仅8KB内容覆盖AODV协议核心定义、报文封装格式与路由表管理逻辑便于在仿真工程中直接引用或二次开发。AODV通过RREQ广播、RREP应答、RERR通告完成按需建路与故障处理这些头文件从协议结构到路由维护为理解上述机制提供了清晰入口。已有243人浏览学习。对于正在开展车载通信、应急通信或军事通信仿真的读者借助这三个头文件可以快速搭建AODV路由模块模拟节点移动条件下的数据转发过程并进一步评估端到端延迟、吞吐量及路由稳定性等关键性能指标为协议优化与场景适配提供代码级参考。1. 移动自组网仿真找上 AODV先弄清楚这个方向要解决什么问题移动自组网MANET没有中心基站节点一边当终端一边当路由器拓扑随时因节点移动而变化。这种网络里最常用的路由协议之一就是 AODVAd hoc On-Demand Distance Vector它属于按需路由只有当节点真正要发数据时才去寻找路由。做移动自组网仿真时你拿到的 aodv.rar 里通常是一套 NS2 工程脚本包含场景生成、协议配置和结果统计。这篇笔记会把这个压缩包背后的东西拆清楚AODV 在仿真里怎么建模、最小可运行的 tcl 脚本怎么写、trace 数据怎么变成论文里的曲线以及我这些年调 AODV 仿真翻过的车。适合正在做 MANET 课程设计、毕业设计或者要评估应急通信、传感器网络路由方案的工程师。2. 先想清楚再动手AODV 仿真的建模对象与工具选型2.1 AODV 的核心机制RREQ/RREP/RERR 与路由表生命周期AODV 是反应式距离向量协议它和 DSDV 这类表驱动协议最大的区别是“平时不干活”。仿真里你会看到静止状态下节点之间没有流量时路由表基本是空的一旦源节点有数据要发而且缓存里没有到目的地的有效路由它就会广播一个 RREQ路由请求消息。这个 RREQ 里带有源节点序列号、目的节点序列号、跳数计数和广播 ID。中间节点收到 RREQ 后先检查自己有没有到目的地的有效路由如果有并且目的序列号比 RREQ 里携带的更新就直接回复 RREP如果没有就把 RREQ 继续广播出去同时在自己的路由表里记录一条到源节点的反向路由。这个过程对应到仿真里就是一次洪泛你可以在 nam 动画里看到蓝色波浪状扩散。当 RREP 沿反向路径回到源节点每个经过的节点都会在路由表里建立到目的地的正向路由跳数为累计跳数有效期由路由表项的超时时间决定。NS2 里 AODV 的默认路由表项超时时间是 3 秒AODV_RTE_TIMEOUT如果 3 秒内没有数据包使用这条路由表项就失效。这个参数直接影响高移动性场景下的性能很多调参的文章会把它改成 5 秒甚至 10 秒来降低路由发现频率但代价是路由指向一个早已不在原位置的邻居反而增加丢包。链路断开时节点会向所有上游节点发送 RERR路由错误上游节点依次删除对应的路由表项下一次发送数据时重新触发 RREQ。这个“发现—建立—失效—再发现”的循环就是移动自组网仿真的核心动态。仿真里如果要观察 AODV 是否正确工作重点盯三件事RREQ 广播会不会无休止传播RREP 是否沿反向路径回传RERR 是否被及时触发。NS2 的 AODV 实现基于 RFC 3561但跟标准存在一些实现细节差异比如它对 MAC 层丢包的处理比较敏感。所以同样一套参数在 NS2 和 NS3 里的结果可能不同这不代表协议错了而是协议栈的耦合方式不同。2.2 仿真工具怎么选NS2/NS3/OMNeT 与 gnu octave 的边界AODV 仿真的主流工具是 NS2、NS3、OMNeT也有用 MATLAB 或者 gnu octave 通信仿真做理论验证的。先说你手里的 aodv.rar绝大多数是 NS2 的 tcl 脚本因为 NS2 从 2.28 开始就自带 AODV 实现网上流传的 MANET 仿真模板基本都以 NS2 为底座。NS2 的优点不是性能而是“老”内置协议模型多AODV 的 bug 和特性都被前人摸透了你遇到任何诡异现象都能搜到别人的踩坑记录。缺点是安装麻烦、trace 格式古老、脚本语法对初学者不友好。NS3 是 NS2 的继任者C 实现AODV 模块在 ns-3.10 之后内置。NS3 的架构更干净还支持 python 绑定但它对 AODV 的默认参数和 NS2 不完全一致比如 Hello 间隔、活跃路由超时时间都存在差异。如果你只看路由协议本身NS3 更现代但如果你想复现和对比别人的论文NS2 反而更容易对上参数。OMNeT 配合 INET 框架也实现了 AODV模块化强适合做多协议、跨层设计的仿真但需要额外安装框架学习曲线最陡。gnu octave 通信仿真适合做快速数值验证比如计算链路稳定概率、路由开销的理论公式推导但不适合做完整的移动自组网协议仿真因为你需要自己实现移动模型、信道竞争和协议状态机工作量不亚于写一个轻量模拟器。我的建议是如果目标是跑通 AODV、出性能指标曲线直接用 NS2如果目标是实现协议改进并做大规模参数扫描用 NS3如果只缺一个对照曲线gnu octave 画图足够。下面的操作都以 NS2 为例因为这是 aodv.rar 最可能的来源。2.3 为什么很多 AODV 仿真还是用 NS2不是为了情怀我接触过不少用 NS3 跑 AODV 的人最后又翻回 NS2核心原因是“可复现性”。NS2 的 AODV 实现里每个关键参数都有明确的默认值你可以直接在 tcl 脚本里用Agent/AODV set hello_period_去改不需要去翻 C 源码。而 NS3 的 AODV 配置要通过属性系统ns3::aodv::RoutingProtocol设置虽然也很 Open但很多教程只告诉你“默认就行”等你想改 RREQ 重传次数时得去源码里翻枚举类型和属性名效率低。另一个原因是 nam 动画。NS2 自带的 nam 工具可以直观看到节点移动、RREQ 洪泛、数据包沿多跳路径转发这对理解 AODV 的按需行为特别有帮助。NS3 本身没有官方图形工具你还要用 NetAnim 或外部可视化插件。做课程答辩时nam 动画比静态曲线更有说服力。所以如果你已经是 NS3 的熟练用户可以用 NS3但如果你是刚开始做自组网仿真我会坚持推荐 NS2。版本上尽量用 2.35这是最后发布的版本坑最少。3. 在 NS2 里把 AODV 跑起来最小实验配置与 tcl 脚本拆解3.1 搭建移动自组网仿真场景节点数、移动模型、通信流量一个完整的移动自组网场景由三部分组成节点部署、移动轨迹、数据流量。节点数一般取 10 到 100常见的是 50。节点部署通常用随机方式但为了可复现应该使用固定的随机种子。移动模型最常用 random waypoint即每个节点随机选一个目标点、随机速度移动到目标点、再暂停一段时间然后重复。暂停时间pause time和最大速度max speed是参数变化的重点一般让速度从 1 m/s 到 20 m/s 变化看 AODV 性能如何随移动性下降。数据流量我一般用 CBR恒定比特率over UDP不用 TCP因为 TCP 的拥塞控制会干扰路由协议的性能判断。CBR 流量需要设置发包间隔和包大小典型的是每 0.25 秒发一个 512 字节的包相当于约 16 kbps。节点对之间建立 UDP 连接常用连接对数 10 到 30 对。在跑大规模实验之前先做一个最小场景10 个节点、3 对连接、速度 5 m/s、仿真时间 50 秒目的只是验证脚本和统计流程能跑通。移动场景文件通常用setdest工具生成。它在 NS2 安装目录indep-utils/cmu-scen-gen/setdest下命令行形式是./setdest -v 1 -n 10 -p 5 -M 5 -t 50 -x 500 -y 500 scen10.txt参数含义-v版本号固定 1-n节点数-p暂停时间秒-M最大速度m/s-t仿真总时间-x -y场景范围 500x500 米。生成的 scen10.txt 里每一行是节点编号和初始坐标后续是移动指令$node_(n) set X_ ...。注意 setdest 生成的坐标是浮点数字符串格式可能不带换行导致 tcl 解析错误我遇到过多次后面避坑章会讲。3.2 AODV 仿真的最小 tcl 脚本从场景生成到 trace 输出下面给出一个可以直接运行的 minimal-aodv.tcl它配置了无线信道、802.11 MAC、队列和 AODV 路由协议创建 10 个节点加载 scen10.txt 的移动场景建立 3 对 UDP/CBR 连接最后输出 trace 和 nam 文件。# 创建仿真器实例 set ns [new Simulator] # 设置 trace 文件nam 用于动画tr 用于数据统计 set tracefd [open mini.tr w] $ns trace-all $tracefd set namfd [open mini.nam w] $ns namtrace-all-wireless $namfd 500 500 # 配置无线物理层和 MAC 层参数 set topo [new Topography] $topo load_flatgrid 500 500 set god_ [create-god 10] set chan_ [new Channel/WirelessChannel] set prop [new Propagation/TwoRayGround] set netif [new Phy/WirelessPhy] set mac [new Mac/802_11] set ifq [new Queue/DropTail/PriQueue] set ll [new LL] set ant [new Antenna/OmniAntenna] # 关键默认天线高度和发送功率影响覆盖范围 $ant set height_ 1.5 $netif set Pt_ 0.2818 $netif set freq_ 914e6 # 配置队列长度未完成的分组可能被丢弃 $ifq set len_ 50 # 配置网络堆栈指定路由协议为 AODV add-to-list $ll add-to-list $mac add-to-list $ifq add-to-list $netif add-to-list $ant add-to-list $prop add-to-list $topo add-to-list $god_ add-to-list $chan_ $ns node-config -adhocRouting AODV \ -llType LL \ -macType Mac/802_11 \ -ifqType Queue/DropTail/PriQueue \ -ifqLen 50 \ -antType Antenna/OmniAntenna \ -propType Propagation/TwoRayGround \ -phyType Phy/WirelessPhy \ -channelType Channel/WirelessChannel \ -topoInstance $topo \ -agentTrace ON \ -routerTrace ON \ -macTrace OFF \ -movementTrace OFF # 创建 10 个无线节点 for {set i 0} {$i 10} {incr i} { set node_($i) [$ns node] $node_($i) random-motion 0 } # 加载 setdest 生成的移动场景 source scen10.txt # 建立 3 对 CBR 流0 - 31 - 42 - 5 set udp0 [new Agent/UDP] set null3 [new Agent/Null] $ns attach-agent $node_(0) $udp0 $ns attach-agent $node_(3) $null3 $ns connect $udp0 $null3 set cbr0 [new Application/Traffic/CBR] $cbr0 set packetSize_ 512 $cbr0 set interval_ 0.25 $cbr0 attach-agent $udp0 # 另一对连接 set udp1 [new Agent/UDP] set null4 [new Agent/Null] $ns attach-agent $node_(1) $udp1 $ns attach-agent $node_(4) $null4 $ns connect $udp1 $null4 set cbr1 [new Application/Traffic/CBR] $cbr1 set packetSize_ 512 $cbr1 set interval_ 0.25 $cbr1 attach-agent $udp1 # 第三对连接 set udp2 [new Agent/UDP] set null5 [new Agent/Null] $ns attach-agent $node_(2) $udp2 $ns attach-agent $node_(5) $null5 $ns connect $udp2 $null5 set cbr2 [new Application/Traffic/CBR] $cbr2 set packetSize_ 512 $cbr2 set interval_ 0.25 $cbr2 attach-agent $udp2 # 等移动场景加载完毕再开启流量避免初始路由建立失败 $ns at 5.0 $cbr0 start $ns at 5.0 $cbr1 start $ns at 5.0 $cbr2 start $ns at 45.0 $cbr0 stop $ns at 45.0 $cbr1 stop $ns at 45.0 $cbr2 stop # 结束前检查 AODV 路由表统计 $ns at 50.0 stop $ns at 50.01 puts \simulation done\ ; $ns halt proc stop {} { global ns tracefd namfd $ns flush-trace close $tracefd close $namfd } puts Starting AODV simulation... $ns run代码逻辑说明node-config一次性指定了整个无线协议栈其中-adhocRouting AODV是核心把路由协议切到 AODV。-ifqLen 50决定了接口队列最多缓存 50 个待发送包如果队列满后面的包直接被丢弃。Propagation/TwoRayGround是两径传播模型它比自由空间模型更接近真实地面环境也是大多数 AODV 论文用的默认模型。$ns node创建节点时move 指令来自 scen10.txt里面设置的坐标范围必须和load_flatgrid一致否则节点会跑到仿真区域外。流量开启时间设为 5 秒是为了给节点完成初始位置更新和邻居发现留出预热时间。如果不预热前几秒发送的数据包会因为路由尚未建立而全部丢失拉低投递率。CBR 的interval_ 0.25表示每 0.25 秒发一个包如果场景里节点间路径跳数多接收端统计的包序号不连续就说明发生了重传或丢包。3.3 关键参数说明无线传播模型、MAC 层与队列长度对 AODV 的影响传播模型仿真里最常被忽略的参数是发送功率Pt_和天线高度height_。TwoRayGround 模型下无线信号被地面反射接收功率与距离的四次方成反比。AODV 能否建立多跳路由完全取决于节点间的链路是否“可达”。NS2 里你可以通过修改Pt_控制覆盖半径默认值 0.2818 在 500x500 场景里覆盖半径约 250 米10 个节点随机分布时平均邻居数足够形成连通网络。如果你把Pt_改小到 0.05可能整个网络都断成碎片AODV 会疯狂发 RREQ 但找不到路由投递率接近零。MAC 层用 802.11 DCF默认不开启 RTS/CTS。路由发现广播包 RREQ 是广播帧不需要 RTS/CTS但数据包是单播如果链路质量差重传会消耗大量时间。Mac/802_11里的basicRate_和dataRate_会影响帧在信道上占用的时间间接影响 AODV 的端到端时延。网络负载大时建议把ifqLen从 50 加大到 100但不要超过 200否则队列排队时延会严重影响实时性指标。还有一个易错点AODV 的 Hello 机制默认开启。NS2 里Agent/AODV set enable_hello_ 1节点每隔 hello_period默认 1 秒广播一次 Hello 消息用来维护邻居列表。Hello 消息本身也是数据帧会占用信道所以在统计路由开销时要把 Hello 带来的额外开销算进去。如果你只想观察 AODV 的基本性能可以在 tcl 里加Agent/AODV set enable_hello_ 0但这样链路断开检测只能依赖 MAC 层反馈可能让 RERR 触发变慢。跑对照实验时这个开关必须固定为一个值否则结果不可比。4. 把数据挖出来trace 文件解析与性能指标计算4.1 NS2 trace 格式事件类型、节点、协议层的字段含义NS2 无线 trace 的每一行以事件类型开头s表示发送sendr表示接收received表示丢弃drop。后面依次是时间、源节点 id、目的节点 id、层级标识、标志、报文源地址、报文目的地址、序列号、包类型和包大小。一个典型行长这样s 6.5 2 4 AGT 0 0.0 5.0 17 3 [MAC 0 0] [CBR 1 4 512]其含义是6.5 秒时节点 2 的应用层AGT向节点 5 发送了一个 CBR 包包序号 17大小 512 字节。注意这里的源节点和目的节点后面还跟了[MAC 0 0]和[CBR ...]两段附加信息。统计投递率时只统计 AGT 层的发送和接收事件因为路由层RTR的发送是转发或者广播 RREQ不能算作用户数据。MAC 层的发送事件是物理帧更不能算。路由层事件里你能看到RREQ、RREP、RERR和RREP_ACK等包类型。统计路由开销时要统计所有 RTR 层发出的 RREQ、RREP、RERR 包的总字节数因为这些包消耗了信道带宽。在 trace 中s事件后跟的包类型字段是AODV的包类型比如s 8.2 1 2 RTR 0 ... [AODV RREQ 10]。这里[AODV RREQ 10]表示 RREQ 的广播 id。4.2 计算分组投递率、端到端时延、路由开销的 awk 脚本下面是一个完整的 awk 脚本它从 mini.tr 中提取三个指标投递率PDR、平均端到端时延、路由开销以发往 RTR 层的 AODV 控制包字节数计。# analyze.awk # 用法: awk -f analyze.awk mini.tr BEGIN { sent 0; recv 0; sum_delay 0; ctl_bytes 0; } { if ($1 s $4 AGT $7 CBR) { sent; # 记录发送时间到数组用源节点和包序号作为键 key $3 : $11; send_time[key] $2; } if ($1 r $4 AGT $7 CBR) { recv; key $3 : $11; if (key in send_time) { delay $2 - send_time[key]; if (delay 0) { sum_delay delay; } } } # 统计AODV控制包RTR层发出的RREQ/RREP/RERR if ($1 s $4 RTR) { # 第8个字段是包类型字段,例如 AODV # 第9个字段是包子类型, 例如 RREQ / RREP / RERR for (i 1; i NF; i) { if ($i RREQ || $i RREP || $i RERR) { # 假设包大小在第12个字段后面或包信息中简化处理 # 用典型AODV包大小RREQ28, RREP20, RERR16 if ($i RREQ) ctl_bytes 28; else if ($i RREP) ctl_bytes 20; else ctl_bytes 16; break; } } } } END { printf 发送分组数: %d\n, sent; printf 接收分组数: %d\n, recv; if (sent 0) { printf 分组投递率: %.2f%%\n, (recv / sent) * 100; } else { printf 分组投递率: 0%%\n; } if (recv 0) { printf 平均端到端时延: %.3f ms\n, (sum_delay / recv) * 1000; } printf AODV控制包总字节数: %d\n, ctl_bytes; }awk 脚本的逻辑说明判断$4 AGT是为了区分应用层还是路由层。CBR 流量在 AGT 层只有s和r事件不会在d事件里对应到应用层丢包。发送时间存在send_time数组里键是源节点:包序号这个组合在 CBR 流里是唯一的因为每个源节点独立编号。如果接收事件对应的发送时间找不到说明包不是从合法路径到达的可能来自旧的转发缓存这样的时延数据不可靠我直接忽略。控制包字节数按 RFC 3561 的包大小近似比解析实际二进制更简单在做相对比较时足够准。跑这个脚本前要先确认 trace 文件里 CBR 的包类型字段确实是CBR。NS2 的 trace 里CBR 应用层的包类型写在第 8 个字段位置附近但不同 NS2 版本字段偏移可能不同。你可以先用head -5 mini.tr看前几行确认第 7 个字段是AGT、第 8 个字段是CBR还是别的。如果字段对不上需要调整 awk 中的列号。这是最常见的统计翻车原因之一。4.3 用 gnu octave 或 matplotlib 画性能曲线统计脚本输出的是单个场景的结果论文里需要的是不同参数下的曲线。比如把最大速度从 1、5、10、15、20 m/s 各跑一遍得到五组投递率和时延数据。可以用 gnu octave 写个小脚本绘图gnu octave 通信仿真里最常用来画曲线因为它能直接读文本文件命令语法接近 MATLAB。下面是用 gnu octave 读取三个文本文件每个文件里是一列投递率值和对应速度并绘制曲线的示例% plot_pdr.m v [1 5 10 15 20]; % m/s pdr_5 load(pdr_5nodes.txt); % 5节点场景 pdr_10 load(pdr_10nodes.txt); % 10节点场景 figure; plot(v, pdr_5, -o, LineWidth, 2, Color, #1f77b4); hold on; plot(v, pdr_10, -s, LineWidth, 2, Color, #d62728); grid on; xlabel(Max speed (m/s)); ylabel(Packet Delivery Ratio (%)); title(AODV PDR vs Node Speed); legend({5 nodes, 10 nodes}, Location, southwest); print(pdr_speed.png, -dpng, -r300);参数说明load读取的文本文件里如果不含矩阵分隔符octave 会把纯数字列读成列向量。plot的-o表示带圆点标记-s表示带方块标记。-r300指定输出 300 dpi 的 PNG论文用图一般需要 300 dpi。如果是在脚本里批量处理可以把for循环包在外面每次运行一个 sim 后重定向输出文件。注意 octave 默认色彩顺序跟 MATLAB 略有不同如果你要严格按 IEEE 配色需要手动指定Color。5. 避坑/常见问题/排查AODV 仿真最常见的翻车现场5.1 现象仿真结果全零或丢包率 100%我第一次跑 AODV 时就遇到投递率是 0trace 文件里全是d事件。检查下来是场景生成器setdest生成的 tcl 文件里节点初始坐标有负数而 topo 范围是 0 到 500负坐标节点直接掉到地图外AODV 找不到任何邻居。原因setdest 旧版本在某些-x -y参数组合下会生成负坐标的小概率事件或者场景文件里混入了空行source时语法报错节点没创建成功。解决先在source scen10.txt前加puts loading scenario再用puts node 0 at [$node_(0) set X_] [$node_(0) set Y_]打印节点坐标确认所有节点坐标都在 0~500 范围内。如果坐标越界重新生成场景文件或者加一行$node_($i) set X_ [expr abs($x)]做绝对值处理。另外如果仿真时间太短比如 10 秒内 CBR 刚启动还没完成路由发现也会造成投递率 0。解决方法是把流量开启时间提前到 1 秒或者把仿真总时长拉长到 50 秒以上给协议足够的时间收敛。5.2 现象路由建立后立刻失效吞吐量断崖下跌高移动速度下AODV 的投递率会从 90% 掉到 30%甚至更低。很多人以为是路由协议不行其实更可能是路由建立的时间大于链路生存时间。原因节点以 20 m/s 移动时相邻节点几秒钟就超出无线覆盖范围。AODV 在发送第一个数据包前要先发 RREQ等 RREP 回来这个过程在 NS2 里通常需要几十毫秒但如果链路在路由建立的瞬间就断裂RREQ 洪泛还没完成包就丢了。解决一是把最大速度控制在 10 m/s 以内做模型验证不要一开始就上 20 m/s二是调整路由表超时时间把Agent/AODV set rte_timeout_从默认 3 秒改成 5 秒让已有路由更“耐用”三是开启 RREP_ACK 机制Agent/AODV set aodv_ack_ 1避免反向路由失效。更直接的办法是降低移动模型的更新频率比如把setdest的 pause time 设为 10 秒而不是 0这样节点是“跑一段停一段”链路保持时间更长AODV 性能更接近真实场景。5.3 现象trace 文件巨大磁盘爆满脚本跑不动50 节点、500 秒仿真默认的 trace 可以到 300MB 甚至 1GB因为 MAC 层和物理层事件全被记录。我在连续跑 100 组参数实验时磁盘半年就满了。原因NS2 默认trace-all会记录每一个无线事件的细节。解决不需要所有层都 trace 时在 node-config 里把-macTrace OFF和-movementTrace OFF只保留-agentTrace ON和-routerTrace ON。这样 trace 文件可以缩小三分之二。另外不要直接对全量 trace 文件反复跑 awk而是在脚本里用awk ... mini.tr summary.txt流式统计统计完就删掉原始 trace。如果磁盘确实紧张可以用ns的trace-annotate只输出关键事件或者用namtrace-all和trace-all共用同一个文件描述符减少重复写入。还有一个习惯每个参数组合独立建一个目录trace 文件放在里面跑完立即压缩避免后期找不到对应关系。5.4 现象复现别人论文的参数结果却完全对不上这是 AODV 仿真里最玄学的一点。很多论文只写了节点数和速度没写随机种子、传播模型、队列长度、Hello 开关甚至没写用的是 NS2 的哪个版本。你按照它写的参数去复现投递率差十个点都很正常。原因NS2 的随机数发生器默认用系统时间当种子两次运行结果不同setdest生成的移动场景文件如果不固定种子整个节点轨迹就不同传播模型默认参数不同步也会导致邻居集合变化。解决第一在 tcl 脚本开头加set rng [new RNG]和$rng seed 12345固定全局随机种子第二用setdest时把-seed参数也固定并保存场景文件在实验记录里写明 hash 值第三在论文里至少列出传播模型、MAC 层、队列长度、Hello 开关、ifqLen、Pt_ 这六个参数。我自己做对比实验时会直接把 tcl 脚本打成压缩包存到 gitcommit 注释里写上所有参数值这样之后回来对数据不用猜。6. 进阶验证把 AODV 与 DSR/OLSR 对比并检查路由表变化的合理性6.1 同一场景跑多种协议对比的公平性AODV 的指标让审稿人认可最好加一个同场景下的协议对比。常见对照组是 DSR 和 OLSR。DSR 是源路由协议包头带完整路径开销比 AODV 大但在移动性较低时投递率高OLSR 是主动式协议需要周期交换拓扑信息节点多时开销高但在拓扑变化快时稳健。在 NS2 里切换协议只改一个字段-adhocRouting DSR或-adhocRouting OLSR。但公平性是关键三个协议必须使用完全相同的移动场景、CBR 流量、传播模型、MAC 层和仿真时间。你不能给 AODV 开了 Hello 而 DSR 没开也不能把队列长度一个设 50 另一个设 100。另外注意 DSR 在 NS2 里需要额外加载 dsrcode路径是/home/ubuntu/ns2.35/ns-2.35/dsr要在编译前配置。对比时统计的指标也要一致比如都只统计 AGT 层的投递率都用同样的时延定义。6.2 用 nam 动画检查 RREQ 洪泛和路由建立比曲线更直观的是 nam 动画。运行完 tcl 后用nam mini.nam打开你能看到节点移动、CBR 包沿多跳路径前进。AODV 正常工作时你会看到某个节点发出一个淡蓝色的圆环扩散开那个就是 RREQ 洪泛随后一条深色路径从目的节点反方向延伸回源节点那就是 RREP 建立的路径。如果 RREQ 洪泛反复出现且没有 RREP 回来说明网络不连通或者目的节点不可达。这个验证方法能帮你快速定位是协议问题还是场景问题。在没有输出 nam 时也可以从 trace 里过滤 RREQ 和 RREP 的时间戳检查是否在 CBR 开始后的几十毫秒内出现了 RREP。如果 RREP 从未出现基本可以断定是链路层无法建立连接。6.3 一个实用技巧把节点移动速度设为 0 做基线验证我最常做的第一个实验不是直接调速度而是先把所有节点设为静止速度 0、暂停时间永远跑同一套流量。这样做有两个目的一是验证自己的 tcl 脚本、统计脚本、绘图流程都没有 bug因为静止网络里 AODV 的投递率理论上接近 99%除非队列溢出或 MAC 冲突二是得到一条“理论下界”曲线后续移动场景的结果不至于比这个基线还好否则说明统计或随机种子出了问题。静止场景里如果投递率不足 95%优先查队列长度和流量负荷而不是怀疑路由协议。这个习惯帮我排掉了很多脚本错误。把速度设 0 的方法很简单setdest的-M 0就行但要注意 NS2 的setdest对-M 0可能拒绝生成移动指令此时手动给每个节点写setdest x y 0并让暂停时间无限大。为了省事我一般先跑到 5 m/s 的同一组随机种子再把移动轨迹全注释掉对比数据。这条路走到这里AODV 仿真的主流程你已经摸清了。最后想强调一句不要迷信默认参数也不要随意改参数骗曲线。把随机种子和传播模型固定下来把所有实验脚本归档别人复现你数据时才不会在第一步就翻车。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询