如何通过Omnet++结果采集功能获取网络层有效消息字节长度总和?
OMNeT++无线网络层有效消息字节长度统计实现方案
一、统计指标说明
先明确三个需要采集的核心指标:
- 每个节点的总发送有效消息字节数(totalSentMessageByteLengths):累加本节点所有应用生成的、向外发送的网络层报文总字节(含报头+数据),所有重传报文均纳入统计
- 每个节点的总接收有效消息字节数(totalReceivedMessageByteLengths):仅统计目的地址为自身的报文,重复重传的同一份报文仅统计1次
- 额外的总接收无效消息字节数(totalInvalidReceivedByteLengths):统计目的地址不匹配、或者重复接收的重传报文总字节
二、核心实现步骤
1. 扩展网络层模块添加统计定义
基于INET框架修改对应网络层(如IPv4、AODV网络层)的NED文件,添加信号与统计声明:
simple NetworkLayer { parameters: @signal[sentByteLength](type=long); @signal[receivedValidByteLength](type=long); @signal[receivedInvalidByteLength](type=long); @statistic[totalSentMessageByteLengths](title="总发送有效字节"; source=sum(sentByteLength); record=vector,last); @statistic[totalReceivedMessageByteLengths](title="总接收有效字节"; source=sum(receivedValidByteLength); record=vector,last); @statistic[totalInvalidReceivedByteLengths](title="总接收无效字节"; source=sum(receivedInvalidByteLength); record=vector,last); // 保留原有端口、参数配置 }
在对应的C++头文件中添加去重缓存变量:
#include <set> #include <tuple> class NetworkLayer : public cSimpleModule { private: // 用(源地址、报文ID、目的地址)唯一标识一份报文,用于重传去重 std::set<std::tuple<L3Address, uint32_t, L3Address>> receivedPacketCache; protected: virtual void handleMessage(cMessage *msg) override; // 保留原有方法定义 };
2. 统计逻辑代码实现
修改网络层C++实现文件,在收发报文节点分别触发统计:
// 源节点发送报文时的统计逻辑 void NetworkLayer::handleSend(cPacket *pkt) { long pktByteLength = pkt->getByteLength(); // 触发发送字节统计信号 emit(registerSignal("sentByteLength"), pktByteLength); // 保留原有发送逻辑 send(pkt, "out"); } // 节点接收报文时的统计逻辑 void NetworkLayer::handleReceive(cPacket *pkt) { long pktByteLength = pkt->getByteLength(); // 解析网络层报文头 auto *ipHeader = dynamic_cast<IPv4Header *>(pkt->getHeader()); L3Address srcAddr = ipHeader->getSourceAddress(); L3Address destAddr = ipHeader->getDestinationAddress(); uint32_t pktId = ipHeader->getIdentification(); auto pktKey = std::make_tuple(srcAddr, pktId, destAddr); // 判断报文有效性 if (destAddr == getInterfaceTable()->getInterface(0)->getNetworkAddress()) { // 未接收过该报文则计入有效统计 if (receivedPacketCache.find(pktKey) == receivedPacketCache.end()) { receivedPacketCache.insert(pktKey); emit(registerSignal("receivedValidByteLength"), pktByteLength); } else { // 重复重传的报文计入无效统计 emit(registerSignal("receivedInvalidByteLength"), pktByteLength); } } else { // 目的地址不匹配计入无效统计 emit(registerSignal("receivedInvalidByteLength"), pktByteLength); } // 保留原有接收处理逻辑 }
3. omnetpp.ini配置调整
原有应用配置仅需修正索引错误(你示例中第二个应用索引应为app[1]),新增全局统计采集配置,用通配符适配25个节点批量生效:
# 修正后的应用配置示例 *.hostA.numApps = 2 *.hostA.app[0].typename = "UdpBasicApp" *.hostA.app[0].destAddresses = "hostB" *.hostA.app[0].destPort = 5000 *.hostA.app[0].messageLength = 1000B *.hostA.app[0].sendInterval = exponential(12ms) *.hostA.app[0].packetName = "UDPData" *.hostA.app[1].typename = "TcpBasicApp" *.hostA.app[1].destAddresses = "hostC" *.hostA.app[1].destPort = 5001 *.hostA.app[1].messageLength = 1024B *.hostA.app[1].sendInterval = exponential(45ms) *.hostA.app[1].packetName = "TCPData" # 新增全局结果采集配置 **.networkLayer.totalSentMessageByteLengths.record = last **.networkLayer.totalReceivedMessageByteLengths.record = last **.networkLayer.totalInvalidReceivedByteLengths.record = last *.result-recording-modes = +last
三、仿真结果提取
仿真运行结束后,打开生成的.sca标量结果文件即可提取数据:
- 单个节点的发送总字节:搜索
[节点名称].networkLayer.totalSentMessageByteLengths的last值 - 单个节点的接收有效总字节:搜索
[节点名称].networkLayer.totalReceivedMessageByteLengths的last值 - 全网总有效字节:将所有节点的对应统计值分别累加即可
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

