NS2中Vector based forward协议Trace文件AGT缺失问题及技术咨询
我来帮你解决这个Aqua-Sim Trace缺失AGT的问题——之前做水下传感器网络路由协议分析时,我也踩过这个坑,下面分点给你讲清楚:
一、AGT层级的定义
AGT是Agent的缩写,在NS2/Aqua-Sim的网络栈架构里,它属于应用层(Application Layer),是数据包生命周期的起点和终点:
- 当你在仿真中配置业务流量(比如CBR、UDP流)时,实际上是通过AGT来生成并发出数据包;
- 当数据包最终到达目的节点后,也是AGT负责接收并标记“成功投递”;
- Trace文件里的AGT事件通常是
AGT send(应用层发出数据包)和AGT recv(应用层收到数据包)这类记录。
二、为什么计算延迟、开销、投递率必须依赖AGT?
这三个核心指标的计算逻辑,本质上都需要基于「应用层的数据包生命周期」,原因如下:
- 数据包投递率(PDR):核心是统计「应用层发出的数据包总数」与「目的节点应用层收到的数据包总数」的比值。如果没有AGT的
send/recv事件,你无法区分原始业务包和网络层的中转转发包——MAC/IP层的Trace事件会包含大量转发包,根本没法准确统计真正要发送的业务量和最终成功投递的量。 - 端到端延迟:指的是数据包从应用层发出到目的节点应用层接收的时间差。如果用网络层的事件(比如IP send到IP recv),得到的只是网络传输阶段的延迟,不仅漏掉了应用层生成数据包的时间,还无法保证是最终到达应用层的有效延迟(比如有些包可能在网络层被丢弃,但应用层不会收到)。
- 路由开销:通常定义为「网络中所有转发的数据包总数」除以「目的节点收到的数据包总数」。这里需要AGT的
recv事件统计成功投递的包数作为分母,再结合MAC/IP层的转发事件统计总转发数,没有AGT的话就没法得到准确的开销计算基准。
三、如何让Aqua-Sim的Trace文件显示AGT事件?
需要从仿真脚本和源码修改两个层面入手,具体步骤如下:
确保仿真脚本中绑定了应用层Agent
在你的.tcl仿真脚本里,必须给发送节点和接收节点绑定对应的应用层Agent(比如UDP/CBR、Null Agent),示例代码如下:# 创建发送端UDP Agent set udp0 [new Agent/UDP] $ns attach-agent $node(0) $udp0 # 创建CBR流量生成器(依赖UDP Agent) set cbr0 [new Application/Traffic/CBR] $cbr0 attach-agent $udp0 # 创建接收端Null Agent(用于接收UDP包) set null0 [new Agent/Null] $ns attach-agent $node(1) $null0 # 连接发送和接收Agent $ns connect $udp0 $null0 # 启动流量 $ns at 1.0 "$cbr0 start" $ns at 10.0 "$cbr0 stop"这里的
Agent/UDP和Agent/Null都属于AGT层级,只有绑定了这些Agent,Trace才会生成对应的AGT事件。修改Aqua-Sim源码开启应用层Trace输出
如果脚本已经绑定Agent但Trace仍无AGT记录,大概率是Aqua-Sim默认屏蔽了应用层的Trace输出。需要修改Aqua-Sim的IP层源码(路径通常为aqua-sim-ng/src/network/ipv4/aqua-sim-ip.cc):- 在处理数据包接收的函数(比如
recv)中,添加AGT接收的Trace输出:// 当数据包到达本节点IP层,且目的地址为本节点时,向上传递到应用层并输出Trace if (pkt->dest() == this->node_id_) { struct hdr_cmn* ch = HDR_CMN(pkt); struct hdr_ip* ih = HDR_IP(pkt); // 判断数据包类型为UDP(可根据你的流量类型调整) if (ch->ptype() == PT_UDP) { Trace::trace(Trace::APP, "AGT", this->node_id_, pkt->uid(), ch->size(), ih->saddr(), ih->daddr(), Scheduler::instance().clock(), "recv"); } } - 在处理数据包发送的函数(比如
sendDown)中,添加AGT发送的Trace输出:struct hdr_cmn* ch = HDR_CMN(pkt); struct hdr_ip* ih = HDR_IP(pkt); if (ch->ptype() == PT_UDP && ch->direction() == hdr_cmn::DOWN) { Trace::trace(Trace::APP, "AGT", this->node_id_, pkt->uid(), ch->size(), ih->saddr(), ih->daddr(), Scheduler::instance().clock(), "send"); }
- 在处理数据包接收的函数(比如
重新编译Aqua-Sim
修改源码后,回到Aqua-Sim根目录执行以下命令重新编译:make clean make重新运行仿真脚本后,生成的Trace文件里就能看到AGT相关的
send/recv事件了。
内容的提问来源于stack exchange,提问作者Hala Jodeh
相关产品推荐
相关产品推荐

