zoukankan      html  css  js  c++  java
  • Oment++ 初学者教程 第4节-将其转变为真实网络

    4.1两个以上的节点

    现在,我们将迈出一大步:创建几个tic模块并将它们连接到网络中。现在,我们将使它们的工作变得简单:一个节点生成一条消息,其他节点继续沿随机方向扔消息,直到它到达预定的目标节点为止。NED文件将需要进行一些更改。首先,该Txc模块将需要具有多个输入和输出门:

    simple Txc10
    {
        parameters:
            @display("i=block/routing");
        gates:
            input in[];  //声明input,ouput两种类型的gate数组
            output out[];
    }
    

    数组[ ]多个门变成gate向量。向量的大小(门数)将在我们使用Txc构建网络的地方确定。

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

    在这里,我们创建了6个模块作为模块向量,并将它们连接起来。
    生成的拓扑如下所示:

    在此版本中,tic[0]将生成要发送的消息。这是在函数initialize()的帮助下完成的,该getIndex()函数返回向量中模块的索引。
    代码的forwardMessage()实质是handleMessage()每当消息到达节点时我们从中调用的函数。它绘制一个随机的gate number,并在该gate上发送message。

    void Txc10::forwardMessage(cMessage *msg)
    {
        // 我们选择随机的一个gate发送信息
        // 我们在0~out[]数组长度之间选择一个随机数
        int n = gateSize("out");
        int k = intuniform(0, n-1);
    
        EV << "Forwarding message " << msg << " on port out[" << k << "]
    ";
        send(msg, "out", k);
    }
    

    当消息到达时tic[3]handleMessage()它将删除该消息。
    请参阅txc10.cc中的完整代码
    练习
    您会注意到,这种简单的“路由”效率不是很高:通常,数据包会在两个节点之间不断跳动一段时间,然后再发送到另一个方向。如果节点不将数据包发送回发送方,则可以在某种程度上进行改进。实现这一点。提示:cMessage::getArrivalGate()cGate::getIndex()。请注意,如果消息不是通过门到达的,而是self-messages,则getArrivalGate()返回NULL
    来源:tictoc10.nedtxc10.ccomnetpp.ini

    4.2信道和内部类型定义

    我们新的网络定义变得非常复杂冗余,尤其是连接部分。让我们尝试简化它。我们注意到的第一件事是,连接始终使用相同的delay参数。与简单模块类似,可以为连接创建类型(它们称为信道)。我们应该创建一个指定延迟参数的信道类型,并将该类型用于网络中的所有连接。

    network Tictoc11
    {
        types:
            channel Channel extends ned.DelayChannel {
                delay = 100ms;
            }
        submodules:
    

    如您所见,我们通过添加一个types字段在网络定义中定义了新的信道类型。此类型定义仅在网络内部可见。它称为局部或内部类型。如果愿意,您也可以将简单模块用作内部类型。
    笔记
    我们通过专门内置来创建通道DelayChannel。(可以在ned包内找到内置信道。这就是为什么我们在extends关键字后使用完整类型名称的ned.DelayChannel的原因
    现在,让我们检查一下该connections部分是如何更改的。

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

    如您所见,我们仅在连接定义内指定通道名称。这样可以轻松更改整个网络的延迟参数。
    来源:tictoc11.nedtxc11.ccomnetpp.ini

    4.3使用双向连接

    如果再检查一下该connections部分,我们将意识到每个节点对都通过两个连接连接。每个方向一个。OMNeT ++ 4支持两种方式的连接,因此让我们使用它们。
    首先,我们必须定义双向(或所谓的inout)门,而不是之前使用的分离inputoutput门。

    simple Txc12
    {
        parameters:
            @display("i=block/routing");
        gates:
            inout gate[];  // declare two way connections
    }
    

    connections部分如下所示:

        connections:
            tic[0].gate++ <--> Channel <--> tic[1].gate++;//tic[0].gate[0]<-->tic[1].gate[0]
            tic[1].gate++ <--> Channel <--> tic[2].gate++;//tic[1].gate[1]<-->tic[2].gate[1]
            tic[1].gate++ <--> Channel <--> tic[4].gate++;
            tic[3].gate++ <--> Channel <--> tic[4].gate++;
            tic[4].gate++ <--> Channel <--> tic[5].gate++;
    }
    

    我们已经修改了门名称,因此我们必须对C ++代码进行一些修改。

    void Txc12::forwardMessage(cMessage *msg)
    {
        // In this example, we just pick a random gate to send it on.
        // We draw a random number between 0 and the size of gate `gate[]'.
        int n = gateSize("gate");
        int k = intuniform(0, n-1);
    
        EV << "Forwarding message " << msg << " on gate[" << k << "]
    ";
        // $o and $i 后缀被用来识别门的双向输入输出
        send(msg, "gate$o", k);
    }
    

    笔记
    gate名称后的特殊$i$o后缀允许我们分别使用连接的两个方向。
    来源:tictoc12.nedtxc12.ccomnetpp.ini

    4.4定义我们的message class

    在此步骤中,不再对目标地址进行硬编码tic[3]-我们绘制一个随机目标,然后将目标地址添加到消息中。

    最好的方法是重写cMessage的子类并将目标添加为数据成员。手动编码消息类通常很乏味,因为它包含许多样板代码,因此我们让OMNeT ++为我们生成该类。消息类规范位于tictoc13.msg

    message TicTocMsg13
    {
        int source;
        int destination;
        int hopCount = 0;
    }
    

    笔记
    有关消息的更多详细信息,请参见OMNeT ++手册的第6节
    设置makefile以便调用消息编译器opp_msgc并生成消息声明tictoc13_m.htictoc13_m.cc从消息声明生成(文件名是根据tictoc13.msg文件名而不是消息类型名生成的)。它们将包含一个TicTocMsg13从[ cMessage]子类生成的类;该类将为每个字段提供getter和setter方法。
    我们将tictoc13_m.h在我们的C ++代码中包含该代码,并且可以将其TicTocMsg13用作任何其他类。

    	#include "tictoc13_m.h"
    

    例如,我们使用以下几行generateMessage()来创建消息并填写其字段。

    	TicTocMsg13 *msg = new TicTocMsg13(msgname);
        msg->setSource(src);
        msg->setDestination(dest);
        return msg;
    

    然后,handleMessage()像这样开始:

    	void Txc13::handleMessage(cMessage *msg)
    {
        TicTocMsg13 *ttmsg = check_and_cast<TicTocMsg13 *>(msg);
    
        if (ttmsg->getDestination() == getIndex()) {
    

    在handleMessage()的参数中,我们将消息作为cMessage*指针。但是,只有TicTocMsg13将msg转换为时,我们才能访问在中定义的字段TicTocMsg13*。纯C样式的强制转换((TicTocMsg13 *)msg)是不安全的,因为如果消息_不是_a TicTocMsg13,则程序最终将崩溃,从而导致错误,而这是很难发现的。
    C ++提供了一种称为的解决方案dynamic_cast。在这里,我们使用check_and_cast<>() OMNeT ++提供的功能:它尝试通过强制转换指针dynamic_cast,如果失败,则会通过错误消息停止模拟,类似于以下内容:

    在下一行中,我们检查目标地址是否与节点的地址相同。该getIndex()成员函数返回子模块向量模块的索引(记住,在我们声明是NED文件tic[6]: Txc13,所以节点地址0..5)。
    为了使模型的执行时间更长,在消息到达其目标之后,目标节点将生成另一条具有随机目标地址的消息,依此类推。阅读完整的代码:txc13.cc
    运行模型时,它将如下所示:

    您可以单击消息以在检查器窗口中查看其内容。双击将在新窗口中打开检查器。(您必须为此暂时停止模拟,或者要非常快地处理鼠标)。检查器窗口显示许多有用的信息;消息字段可/以在“_目录”_页面上看到。

    来源:tictoc13.nedtictoc13.msgtxc13.ccomnetpp.ini
    练习
    在此模型中,在任何给定时刻只有一条消息正在运行:节点仅在另一条消息到达它们时才生成一条消息。我们这样做是为了使跟踪仿真变得更加容易。更改模块类,以便改为定期生成消息。消息之间的间隔应该是一个模块参数,返回指数分布的随机数。

  • 相关阅读:
    机器学习基石笔记12——机器可以怎样学习(4)
    机器学习基石笔记11——机器可以怎样学习(3)
    机器学习基石笔记10——机器可以怎样学习(2)
    机器学习基石笔记9——机器可以怎样学习(1)
    机器学习基石笔记8——为什么机器可以学习(4)
    机器学习基石笔记7——为什么机器可以学习(3)
    转)C++中extern “C”含义深层探索
    CNN图像定位与物体探测_七月算法5月深度学习班第6次课程笔记
    Python 学习之Virtualenv
    电脑使用小技巧
  • 原文地址:https://www.cnblogs.com/li33/p/14610968.html
Copyright © 2011-2022 走看看