Я пытаюсь реализовать модуль, способный принимать и отправлять Ethe rnet пакеты, аналогичные EtherApplications в Inet. Я смог немного поэкспериментировать и создал модуль coumpound, в котором есть два приложения: одно получает пакеты, а другое отправляет их. Однако моя главная цель - сделать одно приложение, которое может сделать и то, и другое. Изучив код обоих EtherAppServer и EtherAppClient , я не вижу причин, по которым EtherAppClient не может принимать пакеты от других EtherAppClients . Я также создал сеть, равную twoHosts в папке inet / examples / Ethe rnet и, если вы удалите EtherAppServer из сети, один хост отправляет пакет, но когда другой получает, модули ll c выводят сообщение: "Получено (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()
{
}
Это реализованный модуль и сеть : используемые сетевые и составные модули . В этой тестовой сети простой модуль s от master [0] отправляет сообщение диспетчеру , заставляя его отправлять пакет. master [1 получает пакет с модулем server и печатает полученное значение. Я хотел бы подчеркнуть, что оба модуля - отправитель и получатель (диспетчер и сервер) - это cSimpleModules , а не ApplicationBase , но я не думаю, что это проблема, так как я тестировал с twoHosts сеть от inet.
Буду признателен за любую помощь.