OMNet++学习笔记(一): 学习资料总结及tictoc例程学习笔记--getting startted

起源:毕业设计需要用到OMNet++,但感觉网上资料较少,所以打算写一系列博客来记录自己学习的过程。这样一方面可以督促自己尽快学习完并做完毕业设计的仿真,另一方面也希望可以帮助到有同样需求的朋友。

1 网络资料

1. 官网

OMNeT++ Tutorials and Technical Articles:https://docs.omnetpp.org/ 

OMNeT++ API Reference:https://doc.omnetpp.org/omnetpp/api/

对于以上两个官方文档的定位,可以参考知乎帖子:OMNeT++教程(从入门到半精通) - 知乎 

即 Tutorials and Technical Articles 帮助我们了解完成一个基本的OMNeT++应用的步骤和流程;而 API Reference 类似字典,帮助我们在需要时具体了解各个api的具体用法。

知乎帖子中的下图就标明了这种关系,api文档是帮助我们灵活使用手册中提到的OMNeT++应用每一步的方式。

image

 2. 网络资源

由上述分析可知,为了快速入门OMNeT++,我们应该阅读 OMNeT++ Tutorials and Technical Articles , 特别是其中的tictoc教程,因为它们介绍了创建一个基本OMNeT++应用的步骤。

如果不想阅读官网英文文档,可以阅读 ShineLee提供的官网文档翻译总结:omnet++:官方文档翻译总结(二) - ShineLe - 博客园

2 tictoc学习笔记

总体概述可参考:omnet++:使用教程 - ShineLe - 博客园

看了一遍有个印象即可,在学习tictoc例程中加深理解。

这里简单写一个总结:

1. OMNeT++三大要素:

  ned(network description): 定义网络拓扑结构,以及对象的属性,如@display, @class等

  c++:定义网络行为

  配置文件:指定网络参数,利用配置文件启动项目

2. Module: 在omnet中,网络中的所有东西(如节点、服务器等)都以module形式定义

  • 最底层的module称为simple module
  • module间可以互相嵌套,没有嵌套的层级限制;
  • module间可以定义继承关系;

可以看出 module 确实相当于C++中的对象,可以用来实例化module对象,而且不同module可以继承、作为“成员变量”

为了定义对象的行为,需要将ned文件中定义的Module与C++中定义的Module联系起来。

3. 配置文件.ini:ned 中的module会有parameter这种属性,它们可以在配置文件.ini中指定

4. OMNeT++是离散事件模拟系统:底层使用二叉堆实现的优先级队列和事件循环(Eventloop)来保存未来事件的集合,这被称为 FES(Future Event Set)或FEL(Future Event List)

image

 启动仿真后,事件执行的伪代码如下:

初始化(initialize) //包括构建模型,添加初始化事件到FES中

while(FES不为空&&仿真未结束)
{
    从FES中取出事件
    t := 该事件发生时间
    执行事件
    (事件执行过程中,可能往FES中添加事件,也可能往FES中删除事件)
}
结束仿真(写入统计数据,etc.)

接下来,我将记录我学习tictoc教程中的一些学习笔记,以便后续复习。

 part 1 getting started

这个例程的功能:一个网络中有两个节点,这两个节点之间来回传递数据包。具体配置工程、编程的步骤可见: omnet++:官方文档翻译总结(二) - ShineLe - 博客园

 这里仅仅分析代码:

1. NED文件

IDE的NED编辑器有两种编辑模式Design、Source。在Design中,通过编辑器右边的Palette完成图形化编辑;在Source中,通过直接编写NED代码完成编辑。

Souce模式下的代码为:

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

其中

  • simple 是前面提到的最底层的module,被称为simple module
  • submodules部分指明构成网络的各个module,connections指明所有module的连接方式
  • submodules中定义时,既可以一句话定义一个简单的simple module对象,如tic:Txc1; 也可以在定义时指明额外的内容,如tic: Txc1{};

详细介绍可参见:OMNeT++ - Simulation Manual

2. cpp文件

目的是定义module的具体行为,同时将cpp中的module和ned中的module进行绑定

#include<string.h>
#include<omnetpp.h>
using namespace omnetpp;
/**
 * Txc1继承自cSimpleModule。在Tictoc1网络中
 * tic和toc模块都是Txc1类对象,它们在仿真一开始就被
 * omnet++创建了
 */
class Txc1 :public cSimpleModule
{
protected:
    //以下虚函数标志了具体功能
    virtual void initialize() override;
    virtual void handleMessage(cMessage *msg) override;
};

//*** ned中的module需要和cc中class进行绑定 ***
Define_Module(Txc1);

void Txc1::initialize(){
    //初始化函数在仿真开始时被调用
    //为了开启tic-toc-tic-toc过程,其中的一个模块需要发送第一个信息,假设这个模块是tic
    if(strcmp("tic",getName())==0){
        //"tictocMsg"是任意一个String,只不过这个String标识了这个消息对象的名字
        cMessage *msg=new cMessage("tictocMsg");
        //在"out" gate中生成并发送第一条消息;
        send(msg,"out");
    }
}

void Txc1::handleMessage(cMessage *msg){
    //当一条消息到达一个module之后,调用handleMessage()方法
    //在这里的消息响应函数中,我们仅仅是把消息发送到其他的module,通过gate 'out'
    //由于tic和toc都会做同样的事情,因此消息实际上是在这两者之间不停反弹的
    send(msg,"out");
}

消息Messages(包、帧、jobs等)和事件Events(定时器、超时等)都是用cMessage对象表示的。

在我们发送(send)或者调度(schedule)它们后,它们将被仿真内核的“scheduled event”或者“future events” List接收并保持,直到指定时间到达或者它们通过handleMessage()把消息传送到了别的module。

3. omnetpp.ini文件

Ini编辑器也有两种模式——Form和Source,这两种模式下的编辑结果也是相同的,只是前者更适合配置仿真内核,后者适合设置模块参数。

这里直接在Souce模式下配置需要仿真的网络network Tictoc1

[General]
network = Tictoc1

之后可以运行程序。

如果遇到了Error,可以通过调试功能/断点功能来排查。而且我们还可以将仿真运行过程中的消息交互日志导出。具体参见原博客 Part 2 - Running the Simulation 的 运行时错误、断点以及结果序列图可视化章节。

3 总结

本章总结了学习OMNeT++的资料,同时记录了创建一个基本的OMNeT++应用需要创建&编辑的三个文件。

 

posted @ 2025-11-04 17:21  碳酸钾K2CO3  阅读(8)  评论(0)    收藏  举报