如何为所有信号节点创建监听器?

How to create listener for all signal nodes?

我正在尝试记录 OMNeT++ 网络中数据包的延迟。我要存储的是一个元组。但是,当目标节点接收到完整的数据包时,它会发出此信号。我想这不是最好的方法,因为通过这种方式,信号与特定节点、目的地相关联,而此信息是 "global"。

一种解决方案可能是使用注册到特定信号的侦听器并收集来自所有节点的所有延迟。但是,如果不实例化额外的 cSimpleModule(侦听器),我该怎么做呢?是否可以有一个 "static" 听众?更一般地说,这是完成我必须做的事情的最佳方式吗?

假设该节点的地址是 int 类型,我建议采用以下解决方案。
1.添加一个新的简单模块GlobalListener:

// GlobalListener.ned
simple GlobalListener { }

// GlobalListener.h
#include <omnetpp.h>

using namespace omnetpp;

class NodesPair {
public:
    NodesPair(int _src, int _dst) : src(_src), dst(_dst) {}
    bool operator<(const NodesPair& other) const {
        if (src == other.src)
            return dst < other.dst;
        return src < other.src;
    }
    int src;  // int is an address
    int dst;
};

class Latency {
public:
    Latency() : latencySum(omnetpp::SimTime::ZERO), entries(0) {}
    simtime_t latencySum;
    int entries;
};

typedef std::map<NodesPair, Latency> LatencyTuples;

class GlobalListener: public cSimpleModule {
protected:
    virtual void initialize();
    virtual void handleMessage(cMessage *msg);
    virtual void finish();
    LatencyTuples latencyTuples;
public:
    void recordLatency(simtime_t latency, int src, int dst);
};

// GlobalListener.cc 
#include "GlobalListener.h"

Define_Module(GlobalListener);

void GlobalListener::initialize() {}

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

void GlobalListener::recordLatency(simtime_t latency, int src, int dst) {
    Enter_Method_Silent();

    NodesPair nodes(src, dst);
    if (latencyTuples.find(nodes) == latencyTuples.end()) {
        // new entry for this pair
        Latency latency;
        latencyTuples[nodes] = latency;
    }
    latencyTuples[nodes].latencySum += latency;
    latencyTuples[nodes].entries += 1;
}

void GlobalListener::finish() {
    for (auto it : latencyTuples) {
        int n = it.second.entries;
        simtime_t meanLat = -1; // -1 means: "no latency"
        if (n > 0) {
            meanLat = it.second.latencySum/n;
        }
        char scalar[64];
        sprintf(scalar, "latency-%d-%d", it.first.src, it.first.dst);
        recordScalar(scalar, meanLat);
    }
}
  1. 在您的 NED 网络中放置一个 GlobalListener 实例并将其命名为 globalListener

  2. 在您的 Node.h 中添加:

    // forward declaration
    class GlobalListener;
    

在 Node 内部 class:

GlobalListener * globalListener;
  1. Node.cc中添加:

    #include "GlobalListener.h"
    
  2. initialize()中在Node.cc中添加:

    cModule * mod = getModuleByPath("globalListener"); // a name from point 2.
    if (mod) {
        globalListener = dynamic_cast<GlobalListener*>(mod);
    } else {
        error("No globalListener module.");
    }
    
  3. 当你想在 Node.cc 中记录延迟时,只需调用:

    simtime_t lat = .... ;
    int src = ....;
    int dst = ....;
    globalListener->recordLatency(a, src, dst);
    

统计数据将在完成模拟时保存为标量。