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

Omnet++带时间戳的全序广播ABCAST实现代码调试求助

带时间戳的全序广播(ABCAST)实现问题及优化建议

我正在OMNeT++中尝试实现带时间戳的全序广播(ABCAST):由单个节点向多节点广播消息,接收消息的节点之间也需互相转发该消息。以下是我的.cc文件和NED文件代码,希望有人帮忙指出需要修改或补充的内容,谢谢。

void Res::initialize()
{
// TODO - Generated method body
seq=0;
signalID = registerSignal("arrival");
timestamp = 1;
if (getIndex() == 0) {
       //Boot the process scheduling the initial message as a self-message.
       char msgname[20];
       sprintf(msgname, "node-%d", getIndex());
       cMessage *msg = new cMessage(msgname);
       scheduleAt(0.0, msg);
   }

}
void Res::handleMessage(cMessage *msg)
{

if (getIndex() == 3) {
// Message arrived.
EV << "Message " << msg << " arrived.\n";
delete msg;
 } else {
forwardMessage(msg);
 }

 }
void Res::forwardMessage(cMessage *msg)
{
int n = gateSize("out");
int k = intuniform(0, n-1);
EV << "Forwarding message " << msg << " on port out [" << k << "]\n";

for (int i = 0; i < n; i++)
{
    cTimestampedValue tmp(timestamp, msg);
    emit(signalID, &tmp);
    cMessage *copy = msg->dup();
    send(copy, "out", i);
}
}
simple Broadcast
{



 parameters:
 @display("i=block/routing");

gates:
 //inout gate[];
 input in[];  // declare in[] and out[] to be vector gates
 output out[]; 

}
network networ
{
types:
submodules:
 node[4]: Broadcast ;
connections:

    
    
          node[0].out++ --> Channel --> node[1].in++;
          //node[1].out++ --> Channel --> node[0].in++;
          node[3].out++ --> Channel --> node[2].in++;
          node[2].out++ --> Channel --> node[3].in++;
          node[0].out++ --> Channel --> node[2].in++;
          node[0].out++ --> Channel --> node[3].in++;
         

}
channel Channel extends ned.DelayChannel
{
delay = 100ms;
}

核心问题与修改建议

1. 节点逻辑不符合全序广播要求

  • 目前仅节点3处理消息,其他节点直接转发,违背ABCAST“所有节点需接收并处理消息”的核心逻辑。应移除getIndex() == 3的判断,让所有节点都执行消息处理流程。
  • 缺少消息去重机制:当前节点收到消息就转发,会导致无限循环(比如节点1→节点2,节点2又转发回节点1)。需给消息添加唯一标识(发送者ID+序列号),让节点只转发未处理过的消息。

2. 时间戳实现无效

  • 固定timestamp=1无法反映消息时序,应改为使用仿真时间(simTime().dbl())或Lamport逻辑时钟,确保时间戳能区分消息先后。
  • cTimestampedValue是用于统计信号的工具,不能给消息本身添加时间戳。需自定义消息类(继承cMessage),添加timestamp、senderId、seqNum等成员变量,实现消息时序标识。

3. 网络拓扑不完整

  • 当前拓扑中节点1与节点2、节点3之间无连接,无法实现节点间互相转发的要求。应改为全连通拓扑,让每个节点的输出端口连接到其他所有节点的输入端口。
  • C类名Res与NED模块名Broadcast不匹配,需统一两者名称,否则OMNeT无法关联模块与代码。

4. 转发逻辑冗余与错误

  • forwardMessage中int k = intuniform(0, n-1);是随机单端口转发的冗余代码,后续循环已实现全端口发送,可直接删除。
  • 初始自消息是普通cMessage,未携带时间戳和标识,需改为发送自定义消息,初始化必要的时序字段。

示例修改方向

自定义消息类

class ABcastMsg : public cMessage {
public:
    int senderId;
    int seqNum;
    double timestamp;

    ABcastMsg(const char *name) : cMessage(name) {}
    ABcastMsg(const ABcastMsg& other) : cMessage(other) {
        senderId = other.senderId;
        seqNum = other.seqNum;
        timestamp = other.timestamp;
    }
    virtual ABcastMsg *dup() const override { return new ABcastMsg(*this); }
};

修改后的initialize方法

void Broadcast::initialize() {
    seqNum = 0;
    signalID = registerSignal("arrival");
    // 记录已处理的消息,避免重复转发
    processedMsgs = new std::unordered_set<std::string>();

    if (getIndex() == 0) {
        ABcastMsg *msg = new ABcastMsg("init-bcast");
        msg->senderId = getIndex();
        msg->seqNum = seqNum++;
        msg->timestamp = simTime().dbl();
        scheduleAt(0.0, msg);
    }
}

修改后的handleMessage方法

void Broadcast::handleMessage(cMessage *msg) {
    ABcastMsg *abMsg = check_and_cast<ABcastMsg*>(msg);
    std::string msgKey = std::to_string(abMsg->senderId) + "-" + std::to_string(abMsg->seqNum);

    if (processedMsgs->find(msgKey) == processedMsgs->end()) {
        // 处理消息:可添加全序排序逻辑
        EV << "Node " << getIndex() << " received message: " << abMsg->getName() 
           << " | Timestamp: " << abMsg->timestamp << "\n";
        processedMsgs->insert(msgKey);

        // 转发消息到所有其他节点
        forwardMessage(abMsg);
    } else {
        // 已处理过,直接删除
        delete msg;
    }
}

修改后的NED全连通拓扑

simple Broadcast
{
    parameters:
        @display("i=block/routing");
    gates:
        input in[];
        output out[];
}

network BroadcastNetwork
{
    types:
    submodules:
        node[4]: Broadcast;
    connections:
        // 全连通拓扑:每个节点连接到其他所有节点
        for i=0..3, for j=0..3 {
            if i != j {
                node[i].out++ --> Channel --> node[j].in++;
            }
        }
}

channel Channel extends ned.DelayChannel
{
    delay = 100ms;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:36:59