OMNet++学习笔记(三): tictoc例程学习笔记--Turning it Into a Real Network
本博客继续记录我学习tictoc教程中的一些学习笔记,以便后续复习。
Part 4 - Turning it Into a Real Network
1. 多于两个节点
实现更真实的网络:从两个节点拓展到多个节点,其中节点0生成消息,其他节点则持续以随机方向传递该消息,直到它抵达预定的目标节点3。
① NED
simple Txc10 { parameters: @display("i=block/routing"); gates: input in[]; // []代表定义的是 gate vector output out[]; } network Tictoc10 { submodules: tic[6]: Txc10; connections: tic[0].out++ --> { delay = 100ms; } --> tic[1].in++; tic[0].in++ <-- { delay = 100ms; } <-- tic[1].out++; tic[1].out++ --> { delay = 100ms; } --> tic[2].in++; tic[1].in++ <-- { delay = 100ms; } <-- tic[2].out++; tic[1].out++ --> { delay = 100ms; } --> tic[4].in++; tic[1].in++ <-- { delay = 100ms; } <-- tic[4].out++; tic[3].out++ --> { delay = 100ms; } --> tic[4].in++; tic[3].in++ <-- { delay = 100ms; } <-- tic[4].out++; tic[4].out++ --> { delay = 100ms; } --> tic[5].in++; tic[4].in++ <-- { delay = 100ms; } <-- tic[5].out++; }
② .cc
#include <stdio.h> #include <string.h> #include <omnetpp.h> using namespace omnetpp; class Txc10 : public cSimpleModule { protected: virtual void forwardMessage(cMessage *msg); virtual void initialize() override; virtual void handleMessage(cMessage *msg) override; }; Define_Module(Txc10); void Txc10::initialize() { if (getIndex() == 0) { // 只有tic[0]才发出消息,这里是利用自己给自己发self-message来实现的 char msgname[20]; sprintf(msgname, "tic-%d", getIndex()); cMessage *msg = new cMessage(msgname); scheduleAt(0.0, msg); } } void Txc10::handleMessage(cMessage *msg) { if (getIndex() == 3) { // 目标的终点 EV << "Message " << msg << " arrived.\n"; delete msg; } else { // 这里转发消息 forwardMessage(msg); } } void Txc10::forwardMessage(cMessage *msg) { // 随机选择一个output gate发送消息 int n = gateSize("out"); int k = intuniform(0, n-1); EV << "Forwarding message " << msg << " on port out[" << k << "]\n"; send(msg, "out", k); }
③ .ini文件
[General]
[Tictoc10]
network = Tictoc10
2. 信道和内部类型定义
在上面的网络定义中,network definition变得十分复杂且长,特别是定义不同module的connect的部分。因此本小节的目的是简化它们。
我们注意到,所有connections具有相同的delay参数,因为我们可以为connects专门创建一个type,叫做channels,来简化modules。j具体代码如下:
①NED
simple Txc11 { parameters: @display("i=block/routing"); gates: input in[]; // declare in[] and out[] to be vector gates output out[]; } network Tictoc11 { types: // 在network内部增加一个types section,它们只在这个network内可见 // 被称为 local or inner type channel Channel extends ned.DelayChannel { delay = 100ms; } submodules: tic[6]: Txc11; connections: tic[0].out++ --> Channel --> tic[1].in++; tic[0].in++ <-- Channel <-- tic[1].out++; tic[1].out++ --> Channel --> tic[2].in++; tic[1].in++ <-- Channel <-- tic[2].out++; tic[1].out++ --> Channel --> tic[4].in++; tic[1].in++ <-- Channel <-- tic[4].out++; tic[3].out++ --> Channel --> tic[4].in++; tic[3].in++ <-- Channel <-- tic[4].out++; tic[4].out++ --> Channel --> tic[5].in++; tic[4].in++ <-- Channel <-- tic[5].out++; }
② .cc ③.ini 没有改变
3. 增加inout gate替代原来的input和output gates
因为连接都是双向的,所以可以直接用two-way (or so called inout) gates来替代原来分离的input和output gates
① NED
simple Txc12 { parameters: @display("i=block/routing"); gates: inout gate[]; // 定义 two way connections } network Tictoc12 { types: channel Channel extends ned.DelayChannel { delay = 100ms; } submodules: tic[6]: Txc12; connections: // 因为是双向门,所以可以直接用<--> tic[0].gate++ <--> Channel <--> tic[1].gate++; tic[1].gate++ <--> Channel <--> tic[2].gate++; tic[1].gate++ <--> Channel <--> tic[4].gate++; tic[3].gate++ <--> Channel <--> tic[4].gate++; tic[4].gate++ <--> Channel <--> tic[5].gate++; }
② .cc
#include <stdio.h> #include <string.h> #include <omnetpp.h> using namespace omnetpp; class Txc12 : public cSimpleModule { protected: virtual void forwardMessage(cMessage *msg); virtual void initialize() override; virtual void handleMessage(cMessage *msg) override; }; Define_Module(Txc12); void Txc12::initialize() { if (getIndex() == 0) { char msgname[20]; sprintf(msgname, "tic-%d", getIndex()); cMessage *msg = new cMessage(msgname); scheduleAt(0.0, msg); } } void Txc12::handleMessage(cMessage *msg) { if (getIndex() == 3) { EV << "Message " << msg << " arrived.\n"; delete msg; } else { forwardMessage(msg); } } void Txc12::forwardMessage(cMessage *msg) { // 从“out”变成"gate" int n = gateSize("gate"); int k = intuniform(0, n-1); EV << "Forwarding message " << msg << " on gate[" << k << "]\n"; send(msg, "gate$o", k); }
4. 定义 message 类
如果一个网络中存在多个消息,而每个消息都用硬编码 tic[3], 这将导致在编写message的handleMessage函数时很麻烦,因此我们定义message类,且这个类只需要定义在.msg文件中,然后makefile中会利用message compiler, opp_msgc, 来生成tictoc13_m.h和tictoc13_m.cc。它们将包含一个[cMessage]的子类,该类为message类的每个字段提供getter和setter方法,具体如下:
① tictoc13.msg
message TicTocMsg13 { int source; int destination; int hopCount = 0; }
② tictoc13.ned: 相较于前面,没有改动
simple Txc13 { parameters: @display("i=block/routing"); gates: inout gate[]; } network Tictoc13 { types: channel Channel extends ned.DelayChannel { delay = 100ms; } submodules: tic[6]: Txc13; connections: tic[0].gate++ <--> Channel <--> tic[1].gate++; tic[1].gate++ <--> Channel <--> tic[2].gate++; tic[1].gate++ <--> Channel <--> tic[4].gate++; tic[3].gate++ <--> Channel <--> tic[4].gate++; tic[4].gate++ <--> Channel <--> tic[5].gate++; }
③ .cc
#include <stdio.h> #include <string.h> #include <omnetpp.h> using namespace omnetpp; // 这个头文件是message compiler利用tictoc13.msg生成的,其中有cMessage的子类 #include "tictoc13_m.h" class Txc13 : public cSimpleModule { protected: virtual TicTocMsg13 *generateMessage(); virtual void forwardMessage(TicTocMsg13 *msg); virtual void initialize() override; virtual void handleMessage(cMessage *msg) override; }; Define_Module(Txc13); void Txc13::initialize() { // Module 0发送第一个消息 if (getIndex() == 0) { // 将第一个消息作为self-message,方便后续消息的处理 TicTocMsg13 *msg = generateMessage(); scheduleAt(0.0, msg); } } void Txc13::handleMessage(cMessage *msg) { // C++ 强制指针类型转换 TicTocMsg13 *ttmsg = check_and_cast<TicTocMsg13 *>(msg); if (ttmsg->getDestination() == getIndex()) { EV << "Message " << ttmsg << " arrived after " << ttmsg->getHopCount() << " hops.\n"; bubble("ARRIVED, starting new one!"); delete ttmsg; EV << "Generating another message: "; TicTocMsg13 *newmsg = generateMessage(); EV << newmsg << endl; forwardMessage(newmsg); } else { forwardMessage(ttmsg); } } TicTocMsg13 *Txc13::generateMessage() { // 随机生成dest int src = getIndex(); // our module index int n = getVectorSize(); // module vector size int dest = intuniform(0, n-2); if (dest >= src) dest++; char msgname[20]; sprintf(msgname, "tic-%d-to-%d", src, dest); // 创建message并且设置src和dest TicTocMsg13 *msg = new TicTocMsg13(msgname); msg->setSource(src); msg->setDestination(dest); return msg; } void Txc13::forwardMessage(TicTocMsg13 *msg) { // 增加跳数 msg->setHopCount(msg->getHopCount()+1); int n = gateSize("gate"); int k = intuniform(0, n-1); EV << "Forwarding message " << msg << " on gate[" << k << "]\n"; send(msg, "gate$o", k); }
总结
在本节中,我们了解了如何定义信道、inout gate和message类,这为我们快速构建大规模网络提供了技术基础
浙公网安备 33010602011771号