我正在尝试实现一个模块,该模块能够接收和发送类似于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 网络。
任何帮助将不胜感激。