You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VEINs/OMNeT++中基于定时器的消息广播机制实现问题

解决方案

1. 先在类中添加成员变量存储待广播消息

首先在MyApp.h的类定义里,新增一个成员变量用来保存待广播的消息副本,避免局部变量丢失:

class MyApp : public BaseWaveApplLayer {
    // 其他已有成员...
    cMessage* RstValueEvt;
    infoMsg* pendingBroadcastMsg = nullptr; // 新增:存储待广播的消息副本
};

2. 修改onWSM函数的消息处理逻辑

修正消息复制的错误,把副本存到成员变量里,同时处理定时器取消时的内存清理:

void MyApp::onWSM(BaseFrame1609_4* frame) {
    infoMsg* wsm = check_and_cast<infoMsg*>(frame);

    // 处理目标为自身的初始消息
    if (wsm->getRecipient() == myId) {
        // 如果定时器已调度,取消并清理旧的待广播消息
        if (RstValueEvt->isScheduled()) {
            cancelEvent(RstValueEvt);
            if (pendingBroadcastMsg != nullptr) {
                delete pendingBroadcastMsg;
                pendingBroadcastMsg = nullptr;
            }
        } else {
            // 计算定时器时长(根据你实现的距离逻辑算出timer值)
            scheduleAt(simTime() + timer, RstValueEvt);
            // 正确复制消息:调用dup()并转为infoMsg*类型
            pendingBroadcastMsg = check_and_cast<infoMsg*>(wsm->dup());
            // 设置消息为广播模式(比如把收件人设为广播标识,例如-1)
            pendingBroadcastMsg->setRecipient(-1);
        }
    }
    // 处理收到其他节点的广播消息:取消自身定时器并清理副本
    else if (wsm->getRecipient() == -1) { // 这里假设-1为广播标识
        if (RstValueEvt->isScheduled()) {
            cancelEvent(RstValueEvt);
            if (pendingBroadcastMsg != nullptr) {
                delete pendingBroadcastMsg;
                pendingBroadcastMsg = nullptr;
            }
        }
    }
}

注意:dup()是OMNeT++中cMessage的成员函数,必须通过指针调用;设置广播收件人标识是为了让后续消息能被全网节点识别接收。

3. 实现handleSelfMsg函数处理定时器到期事件

在handleSelfMsg中监听定时器事件,到期后广播消息并清理资源:

void MyApp::handleSelfMsg(cMessage* msg) {
    if (msg == RstValueEvt) {
        // 检查是否有待广播的消息副本
        if (pendingBroadcastMsg != nullptr) {
            // 调用VEINs的sendDown函数广播消息
            sendDown(pendingBroadcastMsg);
            // sendDown会接管消息所有权,无需手动delete,只需置空指针
            pendingBroadcastMsg = nullptr;
        }
    } else {
        // 处理其他自定义自消息(如果有)
        BaseWaveApplLayer::handleSelfMsg(msg);
    }
}

4. 清理资源(可选但重要)

在类的析构函数中,确保未处理的消息和定时器被清理,避免内存泄漏:

MyApp::~MyApp() {
    cancelAndDelete(RstValueEvt);
    if (pendingBroadcastMsg != nullptr) {
        delete pendingBroadcastMsg;
    }
}

内容的提问来源于stack exchange,提问作者bettyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:01:26