在 OMNet++ 中接收到两次信号

Signals are received twice in OMNet++

我创建了自己的 OMNet++ Listener class 如下:

头文件

#ifndef MYFRAMELISTENER_H_
#define MYFRAMELISTENER_H_



#include <clistener.h>
#include <vector>

class MyFrameListener : public cListener{
public:
    int tempDelmeJustForTest;
    simsignal_t signalIDArray[14];
    int index;
public:
    MyFrameListener();
    virtual ~MyFrameListener();

    virtual void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj);
};

#endif /* MYFRAMELISTENER_H_ */

cc 文件

MyFrameListener::MyFrameListener() {
    this->tempDelmeJustForTest = 0;
}

MyFrameListener::~MyFrameListener() {
}

void MyFrameListener::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj){
        tempDelmeJustForTest++;
}

SimpleModule cc 文件:

void ListenersModule::initialize()
{
    // TODO - Generated method body
    frameListener = new MyFrameListener();
    //subscribe("packetReceivedFromLower",frameListener);
    simulation.getSystemModule()->subscribe("packetReceivedFromLower",frameListener);
}


void ListenersModule::handleMessage(cMessage *msg)
{
    // TODO - Generated method body
}


void ListenersModule::finish(){
    //simulation.getSystemModule()->unsubscribe("packetReceivedFromLower",frameListener);
    recordScalar("My Listened Values", this->frameListener->tempDelmeJustForTest);
}

在这里,我试图通过递增 tempDelmeJustForTest 变量来计算 EtherMACFullDuplex 中接收到的以太网帧数。

EtherMACFullDuplex 是位于 inet/src/inet/linklayer/ethernet/EtherMACFullDuplex.cc 的模块,用于创建 Ethernet phy 端口。

这个class的功能如下图:

void EtherMACFullDuplex::processReceivedDataFrame(EtherFrame *frame)
{
    emit(packetReceivedFromLowerSignal, frame);

    // strip physical layer overhead (preamble, SFD) from frame
    frame->setByteLength(frame->getFrameByteLength());

    // statistics
    unsigned long curBytes = frame->getByteLength();
    numFramesReceivedOK++;
    numBytesReceivedOK += curBytes;
    emit(rxPkOkSignal, frame);

    numFramesPassedToHL++;
    emit(packetSentToUpperSignal, frame);
    // pass up to upper layer
    EV_INFO << "Sending " << frame << " to upper layer.\n";
    send(frame, "upperLayerOut");
}

它发出一个信号 "packetReceivedFromLower" 并且我的监听器已经订阅了它,如上面的代码所示。

问题是计数器显示 tempDelmeJustForTest = 12,而发件人仅发送 6 个以太网帧 。为什么?

此外,我的项目引用了 Core4Inet 项目而不是 Inet 项目。

我猜你正在无意中听到目标主机的 MAC 层和交换机的 MAC 层发出的信号。

通过不仅订阅您自己的模块,还订阅 simulation.getSystemModule() 返回的模块,您可以无意中听到模拟中任何地方发出的所有 packetReceivedFromLower 类型的信号。 "Subscribing to Signals" chapter of the user manual 有更多关于此机制的信息。

如果您想知道您无意中听到的信号是从哪里发出的,您可以使用 receiveSignal 方法的 source 参数。

当发件人发送 6 个以太网帧时,计数器 tempDelmeJustForTest 显示 12,因为方法 processReceivedDataFrame 在您的交换机中涉及 6 次,在目标主机中涉及 6 次。
命令:

simulation.getSystemModule()->subscribe("packetReceivedFromLower",frameListener);

表示监听器将从 任何 元素(即包括开关)接收信号。
你可以在receiveSignal()中添加一行来查看哪个模块发送了信号:

void MyFrameListener::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj){
  EV << "Signal from " << source->getFullPath() << endl;     
  tempDelmeJustForTest++;
}