OMNet++ 例程学习 tictoc10~tictoc13

马上要创造一个真正的网络了
文档链接:https://docs.omnetpp.org/tutorials/tictoc/part4/

TicToc10

TicToc10使用模块向量创建了六个模块,并规划了一定的连接关系,规定每个模块收到一个消息之后会随机发送出去。
一个消息在tic[0]创建,直到tic[3]接收到为止。
一个缺点是消息可能在相连的两个模块之间来回发送很多次(经过测试确实经常陷入循环)

tictoc10.ned

simple Txc10
{
    parameters:
        @display("i=block/routing");
    gates:
        input in[];
        output out[];
}

network Tictoc10
{
    submodules:
        // 用Txc来建立网络的时候,决定向量的大小
        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++;
}

txc10.cc

#include <string.h>
#include <omnetpp.h>
#include <stdio.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::forwardMessage(cMessage *msg){
    // gateSize获取与当前门相连门的数量
    int n = gateSize("out");
    // 从所有与当前门相连的门中任选一个将消息发送出去
    int k = intuniform(0, n-1);

    EV << "Forwarding message " << msg << " on port out[" << k <<"].\n";
    send(msg, "out", k);

}
void Txc10::initialize(){
    if(getIndex() == 0){
        // Boot the process scheduling the initial message as a 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{
        EV << "tic[" << getIndex() << "] is ready to send Message.\n";
        forwardMessage(msg);
    }
}

一个没有解决的问题:ned文件中设计图无法显示出连接关系,只有进入运行状态才能看到连接关系,不知道这是正常状态还是有哪里没有设置正确

TicToc11

任务目标:与TicToc10相同,在TicToc10的基础简化了网络的连接部分。
TicToc11增加了types字段,定义了channel类型的变量Channels ,用来指定统一的延时参数delay

tictoc11.ned

simple Txc11{
	parameters:
	    @display("i=block/routing");
	gates:
        input in[];
        output out[];    
}
network Tictoc11{
    
 	types:
 	    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++; 	    	      
}

txc11.cc

txc10.cc相同

总结
channel有三种类型,分别是:
ned.IdealChannel
ned.DelayChannel,参数delaydisabled(默认false,= true时丢弃通道所有消息)
ned.DatarateChannel
更多关于channel的内容参考https://doc.omnetpp.org/omnetpp/manual/#sec:ned-lang:channels

TicToc12

TicToc11的基础上将门修改成为双向门

tictoc12.ned

simple Txc12{
    parameters:
        @display("i=block/routing");
	gates:
	    inout gate[];		//双向门
}

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++;
}

txc12.cc

只在txc10.cc的基础上修改了以下内容,将

int n = gateSize("out");
int k = intuniform(0, n-1);
EV << "Forwarding message " << msg << " on port out[" << k <<"].\n";
send(msg, "out", k);

修改为

// 门的名字与ned模块中相同
int n = gateSize("gate");
int k = intuniform(0, n-1);
EV << "Forwarding message " << msg << " on port out[" << k <<"].\n";
// inout门使用$o和$i识别输出和输入
// 门的名称+“$o”表示输出门,门的名称+“$i”表示输入门
send(msg, "gate$o", k);

TicToc13

该案例主要研究自定义消息,自定义消息中包括源、目的、跳数三个参数
程序工作流程:第0个模块初始化生成一条消息,任意设置一个目的地址,向任意一个模块发送,接收到消息的模块判断是否是属于它的消息,如果是,就接收消息并销毁,再生成一条新消息继续发送;如果不是,则选择任意一个模块发送出去,直到消息的目的模块收到该消息。

tictoc13.ned

tictoc12.ned相同

tictoc13.msg
cMessage派生一个子类TicTocMsg13,这个子类定义在tictoc13.msg
编译会自动生成tictoc13_m.htictoc13_m.cc两个文件,需要在C++代码中调用tictoc13_m.h

// 该子类包含三个变量,源、目的和跳数
message TicTocMsg13{    
    int source;
    int destination;
    int hopCount = 0;    
}

txc13.cc

#include <stdio.h>
#include <string.h>
#include <omnetpp.h>

using namespace omnetpp;
// 引用头文件,tictoc13.msg编译后自动生成
#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(){
    // 模块0发送第一条消息
    if(getIndex() == 0){
        TicTocMsg13 *msg = generateMessage();
        // 将初始消息调度为自消息
        scheduleAt(0.0, msg);
    }
}
void Txc13::handleMessage(cMessage *msg){
    // 强制类型转换,将收到的的cMessage类的消息转换成TicTocMsg13
    TicTocMsg13 *ttmsg = check_and_cast<TicTocMsg13 *>(msg);
    // 消息的目的地址是当前模块,证明消息到达
    if (ttmsg->getDestination() == getIndex()) {
        // Message arrived.
        EV << "Message " << ttmsg << " arrived after " << ttmsg->getHopCount() << " hops.\n";
        bubble("ARRIVED, starting new one!");
        delete ttmsg;

        // Generate another one.
        EV << "Generating another message: ";
        TicTocMsg13 *newmsg = generateMessage();
        EV << newmsg << endl;
        forwardMessage(newmsg);
    }
    else {
        // We need to forward the message.
        // 这个消息目的地址不是该端口,需要再转发出去
        forwardMessage(ttmsg);
    }

}
TicTocMsg13 *Txc13::generateMessage(){

    int src = getIndex();           // 源地址是当前模块索引号
    int n = getVectorSize();        // 获取门向量的长度 6
    int dest = intuniform(0, n-2);  // 目的地址不包括它自己
    if(dest >= src) dest++;

    char msgname[20];
    sprintf(msgname, "tic-%d-to-%d", 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 gage[" << k << " ].\n";
    send(msg, "gate$o", k);
}

消息往往需要经过很多跳才能从源转发到目的模块。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值