Omnet ++-Ieee8022LlcSocket-以太网实现

时间:2020-03-03 00:33:58

标签: omnet++ inet

我正在尝试实现一个模块,该模块能够接收和发送类似于Inet中的EtherApplications的以太网数据包。我能够进行一些实验,并创建了一个具有两个应用程序的Coumpound模块,一个应用程序接收数据包,另一个发送数据包。但是,我的主要目标是制作一个可以同时实现这两个功能的应用程序。检查 EtherAppServer EtherAppClient 的代码后,我看不到是什么原因导致 EtherAppClient 无法接收来自其他的数据包EtherAppClients 。我还在 inet / examples / Ethernet 文件夹中创建了一个与 twoHosts 相等的网络,如果您从网络中删除了 EtherAppServer ,主机发送一个数据包,但是当另一个接收到时,llc模块会打印一条消息,内容为:“从较低层收到(inet :: Packet)X”,“未知协议,丢弃数据包” 。我只是想了解为什么会这样。

我的应用程序的代码如下。

发件人:

Define_Module(masterDispatcher);

void masterDispatcher::initialize(int stage)
{
    if (stage == inet::INITSTAGE_LOCAL) {
        llcSocket.setOutputGate(gate("lowerLayerOut"));
        llcSocket.setCallback(this);
    }

    else if(stage ==inet::INITSTAGE_APPLICATION_LAYER){
        llcSocket.open(-1, 0xf0);
        destMACAddress = destMACAddress.BROADCAST_ADDRESS;
    }
}

void masterDispatcher::handleMessage(cMessage *msg)
{
    std:: string GateName = msg -> getArrivalGate() -> getFullName();
    std:: string Gate1 = "in";

    if(Gate1.compare(GateName.substr(0,GateName.length())) == 0){
        sendPacket();
    }
    else{
        llcSocket.processMessage(msg);
    }
}


void masterDispatcher::socketClosed(inet::Ieee8022LlcSocket *socket)
{
    //if (operationalState == State::STOPPING_OPERATION && !llcSocket.isOpen())
     //   inet::startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
}

void masterDispatcher::sendPacket()
{

    EV_INFO << "Generating packet " << "'\n";

    inet::Packet *datapacket = new inet::Packet("test", inet::IEEE802CTRL_DATA);

    const auto& frame = inet::makeShared<EthernetFrame>();
    frame->setChunkLength(inet::B(60));
    frame->setTestEther(24);
    datapacket->insertAtBack(frame);

    // Header
    datapacket->addTagIfAbsent<inet::MacAddressReq>()->setDestAddress(destMACAddress);


    auto ieee802SapReq = datapacket->addTagIfAbsent<inet::Ieee802SapReq>();
    ieee802SapReq->setSsap(0xf0);
    ieee802SapReq->setDsap(0xf1);

    emit(inet::packetSentSignal, datapacket);
    llcSocket.send(datapacket);
}



void masterDispatcher::socketDataArrived(inet::Ieee8022LlcSocket*, inet::Packet *msg)
{
    EV_INFO << "Received packet" << msg->getName() << "'\n";

    emit(inet::packetReceivedSignal, msg);

    delete msg;
}

void masterDispatcher::finish()
{
    cancelAndDelete(timerMsg);
    timerMsg = nullptr;
}

接收器:

Define_Module(rec);

void rec::initialize(int stage)
{
    if (stage == inet::INITSTAGE_LOCAL) {
        localSap = par("localSAP");

        // socket
        llcSocket.setOutputGate(gate("out"));
        llcSocket.setCallback(this);

    }
    else if(stage == inet::INITSTAGE_APPLICATION_LAYER)
        registerDsap(localSap);

}

void rec::socketClosed(inet::Ieee8022LlcSocket *socket)
{
 //   if (operationalState == State::STOPPING_OPERATION && !llcSocket.isOpen())
   //     startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
}

void rec::handleMessage(cMessage *msg)
{
    llcSocket.processMessage(msg);
}

void rec::socketDataArrived(inet::Ieee8022LlcSocket*, inet::Packet *msg)
{
    EV_INFO << "Received packet `" << msg->getName() << "'\n";
    const auto& req = msg->peekAtFront<EthernetFrame>();
    if (req == nullptr)
        throw cRuntimeError("data type error: not an EtherAppReq arrived in packet %s", msg->str().c_str());
    emit(inet::packetReceivedSignal, msg);

    inet::MacAddress srcAddr = msg->getTag<inet::MacAddressInd>()->getSrcAddress();
    int srcSap = msg->getTag<inet::Ieee802SapInd>()->getSsap();

    EV << "REC VAL:" << req-> getTestEther() << "\n";
    delete msg;
}

void rec::sendPacket(inet::Packet *datapacket, const inet::MacAddress& destAddr, int destSap)
{
    /*datapacket->addTagIfAbsent<MacAddressReq>()->setDestAddress(destAddr);
    auto ieee802SapReq = datapacket->addTagIfAbsent<Ieee802SapReq>();
    ieee802SapReq->setSsap(localSap);
    ieee802SapReq->setDsap(destSap);

    emit(packetSentSignal, datapacket);
    llcSocket.send(datapacket);
    packetsSent++;*/
}

void rec::registerDsap(int dsap)
{
    EV_DEBUG << getFullPath() << " registering DSAP " << dsap << "\n";

    llcSocket.open(-1, dsap);
}

void rec::finish()
{
}

这是实现的模块和网络:network and compound modules used。在该测试网络中,来自 master [0] 的简单模块 s dispatcher 发送一条消息,以使其发送数据包。 主机[1 ”通过服务器模块接收数据包并打印接收到的值。我想强调一下,发送方和接收方模块(调度程序和服务器)都是 cSimpleModules 而不是 ApplicationBase 模块,但是我认为这不是问题,因为我进行了测试通过inet中的 twoHosts 网络。

任何帮助将不胜感激。

0 个答案:

没有答案