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++应用每一步的方式。

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)

启动仿真后,事件执行的伪代码如下:
初始化(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++应用需要创建&编辑的三个文件。
浙公网安备 33010602011771号