scheduleAt()
函数“发送”自消息,并且您可以指定它们应该在何时返回模块。tictocMsg = new cMessage("tictocMsg"); scheduleAt(5.0, event);
)send(tictocMsg, "out"); tictocMsg = nullptr;
)tictocMsg
变量中的指针,然后安排我们的自消息在模拟的1s时间内返回给我们。(scheduleAt(simTime()+1.0, event);
)ned文件(还是两个结点不变)
simple Txc6
{parameters:@display("i=block/routing");gates:input in;output out;
}network Tictoc6
{submodules:tic: Txc6 {parameters:@display("i=,cyan");}toc: Txc6 {parameters:@display("i=,gold");}connections:tic.out --> { delay = 100ms; } --> toc.in;tic.in <-- { delay = 100ms; } <-- toc.out;
}
cc文件
#include
#include
#include using namespace omnetpp;/*** In the previous models, `tic' and `toc' immediately sent back the* received message. Here we'll add some timing: tic and toc will hold the* message for 1 simulated second before sending it back. In OMNeT++* such timing is achieved by the module sending a message to itself.* Such messages are called self-messages (but only because of the way they* are used, otherwise they are completely ordinary messages) or events.* Self-messages can be "sent" with the scheduleAt() function, and you can* specify when they should arrive back at the module.** We leave out the counter, to keep the source code small.* 在前面的模型中,' tic'和' toc'立即将收到的消息发送回。这里我们将添加一些计时:tic和toc将在将消息发送回之前模拟地保持消息1秒。在omnet++中,这种计时是通过模块向自身发送消息来实现的。这样的消息称为自消息(但仅仅是因为它们的使用方式,否则它们就是完全普通的消息)或事件。可以使用scheduleAt()函数“发送”自消息,并且您可以指定它们应该在何时返回模块。*/
class Txc6 : public cSimpleModule
{private:cMessage *event; // pointer to the event object which we'll use for timing,指向我们将用于计时的事件对象的指针cMessage *tictocMsg; // variable to remember the message until we send it back,变量来记住消息,直到我们将其发送回public:Txc6();virtual ~Txc6();protected:virtual void initialize() override;virtual void handleMessage(cMessage *msg) override;
};Define_Module(Txc6);Txc6::Txc6()
{// Set the pointer to nullptr, so that the destructor won't crash// even if initialize() doesn't get called because of a runtime// error or user cancellation during the startup process.//将指针设置为nullptr,这样即使在启动过程中由于运行时错误或用户取消而没有调用initialize(),析构函数也不会崩溃。event = tictocMsg = nullptr;
}Txc6::~Txc6()
{// Dispose of dynamically allocated the objects,处理动态分配的对象cancelAndDelete(event);delete tictocMsg;
}void Txc6::initialize()
{// Create the event object we'll use for timing -- just any ordinary message.创建用于计时的事件对象——任何普通消息。event = new cMessage("event");// No tictoc message yet.tictocMsg = nullptr;if (strcmp("tic", getName()) == 0) {// We don't start right away, but instead send an message to ourselves// (a "self-message") -- we'll do the first sending when it arrives// back to us, at t=5.0s simulated time.我们不会立即开始,而是向自己发送一条信息(“自我信息”)——当它返回给我们时,我们会在模拟时间t=5.0时进行第一次发送。EV << "Scheduling first send to t=5.0s\n";tictocMsg = new cMessage("tictocMsg");scheduleAt(5.0, event);}
}void Txc6::handleMessage(cMessage *msg)
{// There are several ways of distinguishing messages, for example by message// kind (an int attribute of cMessage) or by class using dynamic_cast// (provided you subclass from cMessage). In this code we just check if we// recognize the pointer, which (if feasible) is the easiest and fastest// method.//有几种方法来区分消息,例如通过消息类型(cMessage的int属性)或通过使用dynamic_cast的类(提供来自cMessage的子类)。在这段代码中,我们只是检查是否识别了指针,这(如果可行)是最简单和最快的方法。if (msg == event) {// The self-message arrived, so we can send out tictocMsg and nullptr out// its pointer so that it doesn't confuse us later. 自我消息到达了,所以我们可以发送tictocMsg和nullptr它的指针,这样以后就不会让我们感到困惑了。EV << "Wait period is over, sending back message\n";send(tictocMsg, "out");tictocMsg = nullptr;}else {// If the message we received is not our self-message, then it must// be the tic-toc message arriving from our partner. We remember its// pointer in the tictocMsg variable, then schedule our self-message// to come back to us in 1s simulated time.如果我们收到的信息不是我们的自我信息,那么它一定是我们的伴侣发来的一字合一的信息。我们记住它在tictocMsg变量中的指针,然后安排我们的自消息在模拟的1s时间内返回给我们。EV << "Message arrived, starting to wait 1 sec...\n";tictocMsg = msg;scheduleAt(simTime()+1.0, event);}
}
if (uniform(0, 1) < 0.1)
,可能会丢失消息delayTime
"模块参数可以设置为"exponential(5)
”(tictoc7。Ned, omnetpp.ini),然后在这里我们每次都会得到不同的延迟。ini配置
[Config Tictoc7]
network = Tictoc7
# argument to exponential() is the mean; truncnormal() returns values from
#指数()的参数是平均值;Truncnormal()返回来自的值
# the normal distribution truncated to nonnegative values
#正态分布截断为非负值
Tictoc7.tic.delayTime = exponential(3s)
Tictoc7.toc.delayTime = truncnormal(3s,1s)
ned文件
simple Txc7
{parameters:volatile double delayTime @unit(s); // delay before sending back message,发送回消息前的延迟@display("i=block/routing");gates:input in;output out;
}network Tictoc7
{submodules:tic: Txc7 {parameters:@display("i=,cyan");}toc: Txc7 {parameters:@display("i=,gold");}connections:tic.out --> { delay = 100ms; } --> toc.in;tic.in <-- { delay = 100ms; } <-- toc.out;
}
cc文件
#include
#include
#include using namespace omnetpp;/*** In this step we'll introduce random numbers. We change the delay from 1s* to a random value which can be set from the NED file or from omnetpp.ini.* In addition, we'll "lose" (delete) the packet with a small probability.* 这一步我们引入随机数。我们将延迟从1更改为一个可以从NED文件或omnetpp.ini中设置的随机值。此外,我们会以很小的概率“丢失”(删除)数据包。*/
class Txc7 : public cSimpleModule
{private:cMessage *event;cMessage *tictocMsg;public:Txc7();virtual ~Txc7();protected:virtual void initialize() override;virtual void handleMessage(cMessage *msg) override;
};Define_Module(Txc7);Txc7::Txc7()
{event = tictocMsg = nullptr;
}Txc7::~Txc7()
{cancelAndDelete(event);delete tictocMsg;
}void Txc7::initialize()
{event = new cMessage("event");tictocMsg = nullptr;if (strcmp("tic", getName()) == 0) {EV << "Scheduling first send to t=5.0s\n";scheduleAt(5.0, event);tictocMsg = new cMessage("tictocMsg");}
}void Txc7::handleMessage(cMessage *msg)
{if (msg == event) {EV << "Wait period is over, sending back message\n";send(tictocMsg, "out");tictocMsg = nullptr;}else {// "Lose" the message with 0.1 probability:“丢失”信息的概率为0.1:if (uniform(0, 1) < 0.1) {EV << "\"Losing\" message\n";delete msg;}else {// The "delayTime" module parameter can be set to values like// "exponential(5)" (tictoc7.ned, omnetpp.ini), and then here// we'll get a different delay every time.//"delayTime"模块参数可以设置为"指数(5)"(tictoc7。Ned, omnetpp.ini),然后在这里我们每次都会得到不同的延迟。simtime_t delay = par("delayTime");EV << "Message arrived, starting to wait " << delay << " secs...\n";tictocMsg = msg;scheduleAt(simTime()+delay, event);}}
}
simple Tic8
{parameters:@display("i=block/routing");gates:input in;output out;
}simple Toc8
{parameters:@display("i=block/process");gates:input in;output out;
}network Tictoc8
{submodules:tic: Tic8 {parameters:@display("i=,cyan");}toc: Toc8 {parameters:@display("i=,gold");}connections:tic.out --> { delay = 100ms; } --> toc.in;tic.in <-- { delay = 100ms; } <-- toc.out;
}
cc文件
#include
#include
#include using namespace omnetpp;/*** Let us take a step back, and remove random delaying from the code.* We'll leave in, however, losing the packet with a small probability.* And, we'll we do something very common in telecommunication networks:* if the packet doesn't arrive within a certain period, we'll assume it* was lost and create another one. The timeout will be handled using* (what else?) a self-message.* 让我们退一步,从代码中去除随机延迟。然而,我们会离开,以很小的可能性失去这个包。我们会做一些在电信网络中很常见的事情:如果数据包在一定时间内没有到达,我们就会假设它丢失了,并创建另一个。超时将使用(还有什么?)一条自消息来处理。*/
class Tic8 : public cSimpleModule
{private:simtime_t timeout; // timeoutcMessage *timeoutEvent; // holds pointer to the timeout self-message 保持指向超时自消息的指针public:Tic8();virtual ~Tic8();protected:virtual void initialize() override;virtual void handleMessage(cMessage *msg) override;
};Define_Module(Tic8);Tic8::Tic8()
{timeoutEvent = nullptr;
}Tic8::~Tic8()
{cancelAndDelete(timeoutEvent);
}void Tic8::initialize()
{// Initialize variables.timeout = 1.0;timeoutEvent = new cMessage("timeoutEvent");// Generate and send initial message.EV << "Sending initial message\n";cMessage *msg = new cMessage("tictocMsg");send(msg, "out");scheduleAt(simTime()+timeout, timeoutEvent);
}void Tic8::handleMessage(cMessage *msg)
{if (msg == timeoutEvent) {// If we receive the timeout event, that means the packet hasn't// arrived in time and we have to re-send it.EV << "Timeout expired, resending message and restarting timer\n";cMessage *newMsg = new cMessage("tictocMsg");send(newMsg, "out");scheduleAt(simTime()+timeout, timeoutEvent);}else { // message arrived// Acknowledgement received -- delete the received message and cancel// the timeout event.EV << "Timer cancelled.\n";cancelEvent(timeoutEvent);delete msg;// Ready to send another one.cMessage *newMsg = new cMessage("tictocMsg");send(newMsg, "out");scheduleAt(simTime()+timeout, timeoutEvent);}
}/*** Sends back an acknowledgement -- or not.*/
class Toc8 : public cSimpleModule
{protected:virtual void handleMessage(cMessage *msg) override;
};Define_Module(Toc8);void Toc8::handleMessage(cMessage *msg)
{if (uniform(0, 1) < 0.1) {EV << "\"Losing\" message.\n";bubble("message lost"); // making animation more informative...使动画更加翔实..delete msg;}else {EV << "Sending back same message as acknowledgement.\n";send(msg, "out");}
}
void Tic9::sendCopyOf(cMessage *msg)
{// Duplicate message and send the copy.cMessage *copy = (cMessage *)msg->dup();send(copy, "out");
}
创建并返回此对象的精确副本,但消息ID除外(克隆被分配了一个新ID)。注意,消息的创建时间也会被复制,因此相同消息对象的克隆具有相同的创建时间。参见cObject了解更多细节。
/*** Creates and returns an exact copy of this object, except for the* message ID (the clone is assigned a new ID). Note that the message* creation time is also copied, so clones of the same message object* have the same creation time. See cObject for more details.* 创建并返回此对象的精确副本,但消息ID除外(克隆被分配了一个新ID)。* 注意,消息的创建时间也会被复制,因此相同消息对象的克隆具有相同的创建时间。* 参见cObject了解更多细节。*/virtual cMessage *dup() const override {return new cMessage(*this);}
ned文件
simple Tic9
{parameters:@display("i=block/routing");gates:input in;output out;
}simple Toc9
{parameters:@display("i=block/process");gates:input in;output out;
}//
// Same as Tictoc8.
//
network Tictoc9
{submodules:tic: Tic9 {parameters:@display("i=,cyan");}toc: Toc9 {parameters:@display("i=,gold");}connections:tic.out --> { delay = 100ms; } --> toc.in;tic.in <-- { delay = 100ms; } <-- toc.out;
}
cc文件
#include
#include
#include using namespace omnetpp;/*** In the previous model we just created another packet if we needed to* retransmit. This is OK because the packet didn't contain much, but* in real life it's usually more practical to keep a copy of the original* packet so that we can re-send it without the need to build it again.* 在前面的模型中,如果需要重传,我们只创建另一个包。这是可以的,因为包包含的内容并不多,但在现实生活中,通常更实际的做法是保留原始包的副本,这样我们就可以重新发送它,而不需要重新构建它。*/
class Tic9 : public cSimpleModule
{private:simtime_t timeout; // timeoutcMessage *timeoutEvent; // holds pointer to the timeout self-messageint seq; // message sequence numbercMessage *message; // message that has to be re-sent on timeoutpublic:Tic9();virtual ~Tic9();protected:virtual cMessage *generateNewMessage();virtual void sendCopyOf(cMessage *msg);virtual void initialize() override;virtual void handleMessage(cMessage *msg) override;
};Define_Module(Tic9);Tic9::Tic9()
{timeoutEvent = message = nullptr;
}Tic9::~Tic9()
{cancelAndDelete(timeoutEvent);delete message;
}void Tic9::initialize()
{// Initialize variables.seq = 0;timeout = 1.0;timeoutEvent = new cMessage("timeoutEvent");// Generate and send initial message.EV << "Sending initial message\n";message = generateNewMessage();sendCopyOf(message);//拷贝并发送scheduleAt(simTime()+timeout, timeoutEvent);
}void Tic9::handleMessage(cMessage *msg)
{if (msg == timeoutEvent) {// If we receive the timeout event, that means the packet hasn't// arrived in time and we have to re-send it.EV << "Timeout expired, resending message and restarting timer\n";sendCopyOf(message);scheduleAt(simTime()+timeout, timeoutEvent);}else { // message arrived// Acknowledgement received!EV << "Received: " << msg->getName() << "\n";delete msg;// Also delete the stored message and cancel the timeout event.EV << "Timer cancelled.\n";cancelEvent(timeoutEvent);delete message;// Ready to send another one.message = generateNewMessage();sendCopyOf(message);scheduleAt(simTime()+timeout, timeoutEvent);}
}cMessage *Tic9::generateNewMessage()
{// Generate a message with a different name every time.char msgname[20];sprintf(msgname, "tic-%d", ++seq);cMessage *msg = new cMessage(msgname);return msg;
}void Tic9::sendCopyOf(cMessage *msg)
{// Duplicate message and send the copy.cMessage *copy = (cMessage *)msg->dup();send(copy, "out");
}/*** Sends back an acknowledgement -- or not.*/
class Toc9 : public cSimpleModule
{protected:virtual void handleMessage(cMessage *msg) override;
};Define_Module(Toc9);void Toc9::handleMessage(cMessage *msg)
{if (uniform(0, 1) < 0.1) {EV << "\"Losing\" message " << msg << endl;bubble("message lost");delete msg;}else {EV << msg << " received, sending back an acknowledgement.\n";delete msg;send(new cMessage("ack"), "out");}
}