如何在INET框架的UDP数据包中添加自定义测试消息或数值数据?
在INET的UdpBasicApp中为UDP数据包添加负载数据/消息
方法1:添加自定义字符串消息
直接在原有的ApplicationPacket中填充字符串内容,步骤如下:
- 构造包含自定义内容的字符串(比如带序列号的测试消息)
- 同步设置负载的长度为字符串长度(或适配配置的
messageLength参数) - 将字符串字节复制到负载缓冲区
修改后的sendPacket()方法示例:
void UdpBasicApp::sendPacket() { std::ostringstream str; str << packetName << "-" << numSent; Packet *packet = new Packet(str.str().c_str()); if(dontFragment) packet->addTag<FragmentationReq>()->setDontFragment(true); const auto& payload = makeShared<ApplicationPacket>(); // 构造自定义测试消息 std::string testMsg = "UDP Test Msg #" + std::to_string(numSent); // 设置负载长度为消息实际长度(也可改用par("messageLength")并做截断/填充) payload->setByteLength(testMsg.size()); // 将字符串复制到负载的可修改字节缓冲区 std::copy(testMsg.begin(), testMsg.end(), payload->getMutableBytes()); payload->setSequenceNumber(numSent); payload->addTag<CreationTimeTag>()->setCreationTime(simTime()); packet->insertAtBack(payload); L3Address destAddr = chooseDestAddr(); emit(packetSentSignal, packet); socket.sendTo(packet, destAddr, destPort); numSent++; }
如果要保留配置的messageLength参数(允许通过OMNeT++ ini文件设置长度),可调整为:
// 从配置读取消息长度 B msgLen = par("messageLength"); payload->setChunkLength(msgLen); std::string testMsg = "UDP Test Msg #" + std::to_string(numSent); // 若消息长度超过配置值则截断,否则填充0 size_t copyLen = std::min(testMsg.size(), (size_t)msgLen.get()); std::copy(testMsg.begin(), testMsg.begin() + copyLen, payload->getMutableBytes()); if (copyLen < msgLen.get()) { std::fill(payload->getMutableBytes() + copyLen, payload->getMutableBytes() + msgLen.get(), 0); }
方法2:添加数值型数据(如序列号、时间戳)
如果需要发送结构化数值数据(比如整数、时间戳),可将数值转换为字节序列写入负载,注意使用网络字节序保证跨平台兼容性:
修改后的sendPacket()方法示例(发送序列号+仿真时间戳):
void UdpBasicApp::sendPacket() { std::ostringstream str; str << packetName << "-" << numSent; Packet *packet = new Packet(str.str().c_str()); if(dontFragment) packet->addTag<FragmentationReq>()->setDontFragment(true); const auto& payload = makeShared<ApplicationPacket>(); // 定义结构化数值数据 struct TestPayload { uint32_t sequence; // 序列号(网络字节序) double timestamp; // 仿真时间戳 } data; // 转换为网络字节序(整数类型需要,浮点类型可根据需求处理) data.sequence = htonl(numSent); data.timestamp = simTime().dbl(); // 设置负载长度为结构体大小 payload->setByteLength(sizeof(data)); // 将结构体字节复制到负载缓冲区 std::memcpy(payload->getMutableBytes(), &data, sizeof(data)); payload->setSequenceNumber(numSent); payload->addTag<CreationTimeTag>()->setCreationTime(simTime()); packet->insertAtBack(payload); L3Address destAddr = chooseDestAddr(); emit(packetSentSignal, packet); socket.sendTo(packet, destAddr, destPort); numSent++; }
接收端提取数据示例
在接收方的UdpBasicApp中,可在handleMessage()方法里提取负载数据:
提取字符串消息
void UdpBasicApp::handleMessage(cMessage *msg) { if (msg->isSelfMessage()) { // 处理自消息逻辑(如定时发送) sendPacket(); scheduleNextPacket(); } else { // 处理收到的UDP数据包 Packet *packet = check_and_cast<Packet*>(msg); auto payload = packet->peekAtBack<ApplicationPacket>(); // 提取字符串内容 std::string receivedMsg(payload->getBytes(), payload->getBytes() + payload->getByteLength()); EV_INFO << "Received string message: " << receivedMsg << endl; delete packet; } }
提取数值数据
void UdpBasicApp::handleMessage(cMessage *msg) { if (msg->isSelfMessage()) { sendPacket(); scheduleNextPacket(); } else { Packet *packet = check_and_cast<Packet*>(msg); auto payload = packet->peekAtBack<ApplicationPacket>(); // 解析结构化数值数据 struct TestPayload { uint32_t sequence; double timestamp; } data; std::memcpy(&data, payload->getBytes(), sizeof(data)); // 转换回主机字节序 uint32_t seq = ntohl(data.sequence); EV_INFO << "Received sequence: " << seq << ", Timestamp: " << data.timestamp << endl; delete packet; } }
内容的提问来源于stack exchange,提问作者Omaima Younsi
相关产品推荐
相关产品推荐

