OMNeT++学习---TicToc(1)

       首先,让我们从一个由两个节点组成的“网络”开始。节点将做一些简单的事情:其中一个节点将创建一个数据包,两个节点将继续来回传递相同的数据包。我们将节点称为“tic”和“toc”。

以下是从头开始实施第一个模拟的步骤:

1.创建一个名为tictoc的工作目录,并cd到此目录。

2.通过创建拓扑文件来描述您的示例网络。拓扑文件是一个文本文件,用于标识网络的节点及其之间的链接。您可以使用自己喜欢的文本编辑器创建它。我们称之为tictoc1.ned:

tictoc1.ned

simple Txc1
{
    gates:
        input in;
        output out;
}

//Txc1的两个实例(tic和toc)都是双向连接的
// tic和toc将消息传递给另一个

network Tictoc1
{
    submodules:
        tic: Txc1;
        toc: Txc1;
    connections:
        tic.out --> {  delay = 100ms; } --> toc.in;
        tic.in <-- {  delay = 100ms; } <-- toc.out;
}

       该文件最好从下往上阅读。它是说:

  • Tictoc1是一个网络,由两个子模块tic和toc组合而成。tic和toc是名为Txc1的相同模块类型的实例。我们将tic的输出门(命名为)连接到toc的输入门(命名为),反之亦然(network ... { ... })。两种方式都会有100ms的传播延迟;
  • Txc1是一个简单的模块类型(这意味着它在NED级别上是原子的,并且将在C ++中实现)。Txc1有一个名为in的输入门,一个输出门名为out(simple ... { ... }

 

  3.我们现在需要实现简单模块Txc1的功能。这是通过编写C ++文件txc1 :: cc来实现的

#include 
#include 


class Txc1 : public cSimpleModule
{
  protected: 
    virtual void initialize();
    virtual void handleMessage(cMessage *msg);
};

// The module class needs to be registered with OMNeT++
Define_Module(Txc1);

void Txc1::initialize()
{
    // 模拟开始时调用Initialize来引导tic-toc-tic-toc进程
    // 其中一个模块需要发送第一条消息。让它成为'tic'

    // 是Tic还是Toc?
    if (strcmp("tic", getName()) == 0)
    {
        // 在门“out”上创建并发送第一条消息
        //“tictocMsg”是任意字符串,它将是消息对象的名称
        cMessage *msg = new cMessage("tictocMsg");
        send(msg, "out");
    }
}

void Txc1::handleMessage(cMessage *msg)
{
    // 每当消息到达模块时,都会调用handleMessage()方法
    //在这里,我们只是通过‘out’门将它发送到另一个模块
    //因为'tic'和`toc'都是相同的,所以消息会在两者之间反弹
    send(msg, "out");
}

       简单模块Txc1由C ++类Txc1来表示,它是cSimpleModule的子类,并注册在OMNeT++的 Define_Module()宏里。我们从cSimpleModule重新定义了两个方法:initialize()和handleMessage()。它们是从仿真内核里调用的:第一个只使用一次,第二个是在消息到达模块时使用。

initialize()中,我们创建一个消息对象(cMessage),通过“out”门发送它。由于此“out”门连接到另一个模块的输入门,因此仿真内核会在handleMessage()的参数中将此消息传递给另一个模块--- NED文件中,在100ms传播延迟之后将它分配到链路中。另一个模块只是将其发回(另外100ms延迟),因此它将导致连续的乒乓。

Messages(数据包,帧,作业等)和events(定时器,超时)都是由OMNeT ++中的cMessage对象(或其子类)表示。在发送或安排它们之后,仿真内核将他们保存在“scheduled events”或“future events”列表中,直到它们到来并通过handleMessage()传递给模块。

请注意,此模拟中没有内置停止条件:它将永远持续下去。您将能够从GUI停止它。(您还可以在配置文件中指定模拟时间限制或CPU时间限制,但我们在教程中不这样做。)

4.我们现在创建Makefile,它将帮助我们编译和链接我们的程序以创建可执行文件tictoc

$ opp_makemake

    此命令现在应该已在工作目录tictoc中创建了一个Makefile

5.现在让我们通过发出make命令来编译和链接我们的第一个模拟:

$ make

    如果存在编译错误,则需要纠正它们并重复make,直到获得无错误的编译和链接。

6.如果您现在启动可执行文件,它会抱怨它无法找到omnetpp.ini文件,因此您必须创建一个。omn​​etpp.ini告诉模拟程序您要模拟哪个网络(是的,几个网络可以存在于同一个模拟程序中),您可以将参数传递给模型,明确指定随机数生成器的种子等。

创建以下非常简单的omnetpp.ini:

[General]
network = Tictoc1

    tictoc2和进一步的步骤将共享以下omnetpp.ini:

# This file is shared by all tictoc simulations.
# Lines beginning with `#' are comments

[General]
# nothing here

[Config Tictoc1]
network = Tictoc1

[Config Tictoc2]
network = Tictoc2

[Config Tictoc3]
network = Tictoc3

[Config Tictoc4]
network = Tictoc4
Tictoc4.toc.limit = 5

[Config Tictoc5]
network = Tictoc5
**.limit = 5

[Config Tictoc6]
network = Tictoc6

[Config Tictoc7]
network = Tictoc7
# argument to exponential() is the mean; truncnormal() returns values from
# the normal distribution truncated to nonnegative values
Tictoc7.tic.delayTime = exponential(3s)
Tictoc7.toc.delayTime = truncnormal(3s,1s)

[Config Tictoc8]
network = Tictoc8

[Config Tictoc9]
network = Tictoc9

[Config Tictoc10]
network = Tictoc10

[Config Tictoc11]
network = Tictoc11

[Config Tictoc12]
network = Tictoc12

[Config Tictoc13]
network = Tictoc13

[Config Tictoc14]
network = Tictoc14

[Config Tictoc15]
network = Tictoc15
record-eventlog = true

[Config Tictoc16]
network = Tictoc16
**.tic[1].hopCount.result-recording-modes = +histogram
**.tic[0..2].hopCount.result-recording-modes = -vector

7.完成上述步骤后,通过发出以下命令启动模拟

$ ./tictoc

  现在应该已经打开OMNeT ++模拟窗口

8.按工具栏上的“运行”按钮开始模拟,您应该看到的是tic和toc正在相互交换消息。

       主窗口工具栏显示模拟时间。这是虚拟时间,它与程序执行的实际(或挂钟)时间无关。实际上,您可以在一个真实世界中模拟多少秒,这在很大程度上取决于硬件的速度,更取决于仿真模型本身的性质和复杂性。请注意,节点处理消息需要零模拟时间。使模拟时间在此模型中通过的唯一因素是连接上的传播延迟。

9.您可以使用图形窗口顶部的滑块来减慢动画速度或加快速度。您可以通过按F8(相当于工具栏上的STOP按钮),单步执行(F4),使用(F5)或不使用(F6)动画运行来停止模拟。F7(快速模式)完全关闭跟踪功能以获得最大速度。请注意主窗口状态栏上的事件/秒和simsec / sec计量器。

10.您可以通过单击“关闭”图标或选择“文件”|“退出”来退出模拟程序。

  • 要点:

  1. 创建NED文件(在NED中给出网络的拓扑结构),拓扑结构包含简单模块(主要包含input门和output门)、复合模块、网络模块(包含子模块和连接)
  2. 创建C++文件(*.cc)为每个简单模块实现功能,每个简单模块的类名必须与NED中简单模块的名字保持一致;简单模块类继承于系统库中提供的cSimpleModule类,类中一般方法包含初始化函数initialize(),以及接受到消息后的处理函数handleMessage();类定义完成后,必须使用宏Define_Module()进行注册
  3. Build工程会自动生成makefile文件,并对源代码进行编译(命令行实际是调用opp_makemake工具来自动生成makefile文件),生成可执行程序
  4. 此时模拟程序还无法启动,需要创建omnetpp.ini文件;ini文件中主要描述一下需要模拟定义的哪个网络(一个模拟程序中可以定义多个网络),已经如何给该网络模型传递参数等等
  5. 通过debug、run或者直接在命令行中运行生成的可执行程序,模拟就跑起来了。模拟中可以一步一步运行,可以调节运行的速度,以及动画的速度。
  •   容易出错的地方:

1)NED和cc文件中模型的类名必须保持一致;

2)不要忘记Define_Module();

3)cc文件中   不要忘记#include ,using namespace omnetpp;

你可能感兴趣的:(omnet++)