TICTIC 8
本实例要求:
- toc段在接收时将有一定概率丢包;
- toc段在丢包时需要在仿真中有动画效果显示该部分丢包;
- toc段在丢包后tic段将补发数据包。
首先定义tic8的类:
class Tic8 : public cSimpleModule//1~7均是定义的txc,这里为了补发消息,定义了两个不同的模块,
{
private:
simtime_t timeout; // simtime_t是仿真实现类,这里把timeout定义成了仿真时间,目的是执行超时时的补发行为
cMessage *timeoutEvent = nullptr; // 在类中new是不合法的,所以先保存一个指向消息的空指针,在后边初始化的时候补全指针。
public:
virtual ~Tic8();//析构函数,每个这种最后会终结的情况似乎都有析构函数,为了回收内存?
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
tic8中的初始化函数:
void Tic8::initialize()
{
timeout = 1.0;//默认单位是秒
timeoutEvent = new cMessage("timeoutEvent");
EV << "Sending initial message\n";
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out");//生成msg作为初始消息发出去
scheduleAt(simTime()+timeout, timeoutEvent);//在当前仿真时间+一秒后,tic8模块会收到timeoutEvent
}
tic8中的处理函数:
void Tic8::handleMessage(cMessage *msg)
{
if (msg == timeoutEvent) {//tic收到的不是toc返回的消息,而是自己设置的在一秒后发送的子消息,这意味着接收消息超时,在这里即是丢包
EV << "Timeout expired, resending message and restarting timer\n";
cMessage *newMsg = new cMessage("tictocMsg");
send(newMsg, "out");//重新new一个消息并且发送
scheduleAt(simTime()+timeout, timeoutEvent);//继续设置定时器,监视toc是否丢包
}
else { //收到了正常的消息
EV << "Timer cancelled.\n";
cancelEvent(timeoutEvent);
delete msg;
cMessage *newMsg = new cMessage("tictocMsg");
//这里删除了之前收到的消息,又发了一个新的消息,后面会说一下这个地方。
send(newMsg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);//同样,还是要监视是否超时
}
}
这里有个需要注意的地方,实际上tic并不是把从toc收来的信息再发送给toc,而是产生了新消息,如果想要在toc再次收到同一条消息,可以把代码
delete msg;
cMessage *newMsg = new cMessage("tictocMsg");
更改为:
send(msg, "out");//test
(其实是有点画蛇添足的,单纯闲着没事发现的)
之后要定义toc8的类,toc是不主动 发送信息,也没有重发送的功能,所以不需要对它有额外的设置,它只要能处理信息就好
class Toc8 : public cSimpleModule
{
protected:
virtual void handleMessage(cMessage *msg) override;
};
最后就是toc处理信息的部分了,它有一部分几率丢包,并且有个动画演示功能:
void Toc8::handleMessage(cMessage *msg)
{
if (uniform(0, 1) < 0.1) {
EV << "\"Losing\" message.\n";
bubble("message lost"); //动画演示功能,会显示"message lost"
delete msg;//丢包,删了
}
else {
EV << "Sending back same message as acknowledgement.\n";
send(msg, "out");
}
}