目 录
OMNET++简介 ·····························································································2
概述······························································································································································2
1.1 OMNeT++框架·····································································································································2
1.1.1 OMNeT++组成························································································································ 2
1.1.2 OMNeT++结构························································································································ 3
1.2 OMNeT++的安装·································································································································4
1.3 OMNeT++语法·····································································································································5
2.3.1 NED 语言 ································································································································ 5
1.3.1.1 NED 总概述 ····················································································································· 5
1.3.1.2 Ned 描述的组件 ··············································································································· 5
1.3.1.3 函数 ·································································································································· 8
1.3.2 简单模块 ································································································································ 9
1.3.2.1 OMNET++中离散事件································································································· 9
1.3.2.2 包传输模型···················································································································· 10
1.3.2.3 定义简单模块················································································································ 11
1.3.2.4 简单模块中的主要成员函数 ························································································ 12
1.3.3 消息 ······································································································································ 13
1.3.3.1 cMessage 类···················································································································· 13
1.3.3.2 消息定义 ······················································································································· 14
1.3.3.3 消息的收发···················································································································· 14
1.3.4 模块参数、门及连接的访问 ······························································································· 16
1.3.4.1 消息参数的访问············································································································· 16
1.3.4.2 门和连接的访问············································································································· 17
1.3.4.3 门的传输状态················································································································· 18
1.3.3.4 连接的状态 ···················································································································· 19
1.4 仿真过程 ································································································································· 19
1.5 配置文件 omnetpp.ini·············································································································· 20
1.6 结果分析工具·························································································································· 21
1.6.1 矢量描绘工具 Plove········································································································· 21
1.6.2 标量工具 Scalar················································································································ 21
结束语············································································································································ 22
1
概述
Omnet++简介
OMNeT++是 Objective Modular Network TestBed in C++的英文缩写,它是开源的基于组
件的模块化的开放网络仿真平台,是近年来在科学和工业领域里逐渐流行的一种优秀的网络
仿真平台。OMNeT++作为离散事件仿真器,具备强大完善的图形界面接口和可嵌入式仿真
内核,同 NS2,OPNET 和 JavaSim 等仿真平台相比,OMNeT++可运行于多个操作系统平台,
可以简便定义网络拓扑结构,具备编程,调试和跟踪支持等功能。OMNeT++主要用于通信
网络和分布式系统的仿真,目前最高版本为 OMNeT3.3p1。
1.1 OMNeT++框架
1.1.1 OMNeT++组成
OMNeT++主要由六个部分组成:仿真内核库(simulation kernel library,简称 Sim),
网络描述语言的编译器(network description compiler, nedc),图形化的网络编辑器
(graphical network description editor,GNED),仿真程序的图形化用户接口-Tkenv,
仿真程序的命令行用户接口-Cmdenv,图形化的输出工具-Plove 和 Scalar。 Sim 是仿真
内核和类库,用户编写的仿真程序要同 Sim 连接,Sim 在 OMNeT++中占据最为核心重要的地
位。下面详细介绍的另外两重要组成部分。
(1).网络描述(NED)语言
NED 是模块化的网络描述语言。网络描述包括大量的对组件的描述,如通道,简单和复
合模块的类型。这些组件描述可用于各种不同的网络描述中。NED 语言用来定义模型中的网
络拓扑结构,较为简单的网络拓扑可以使用 GNED,但复杂网络的拓扑描述还应该用 NED 源
文件方式书写。
(2).用户接口
OMNeT++的用户接口用于实现仿真程序的人机交互,OMNeT++允许模型内部机制对用户
可视化,也允许用户启动和终止仿真,并更改模型内部的变量。OMNeT++中的图形化接口是
一个用户工具,可方便用户了解模型内部的运行机制。
2
用户接口和仿真内核的交互是通过一个已定义的接口实现的。无需改变仿真内核,就可
以实现不同类型的用户接口。同样无需更改模型文件,仿真模型可在不同接口下运行。用户
以在强大图形化用户接口下测试和调试仿真程序,并最后可在简单快速的用户接口中运行,
而且该接口支持批处理。
目前 OMNeT++支持两种用户接口,即 Tkenv 和 Cmdenv。对仿真进行的测试和调试可以
在 Tkenv 接口下进行,Tkenv 是一个简便易用的图形窗口化的用户接口,Tkenv 支持跟踪,
调试和执行仿真的功能。它在执行仿真过程中的任意时刻都能够提供详细的状态信息。Tkenv
的主要特征有:各模块的文本输出有其独立的窗口,仿真过程中可以在 Tkenv 窗口中看到自
传消息,支持仿真动画,标记断点,具有检查窗口,可以检查和改变模型中的变量,执行过
程中仿真结果的图形化显示并且结果可以用柱状图和时间序列图显示,仿真可重新进行,快
照文件用于显示模型的详细信息。
Cmdenv 接口用于实际的仿真实验,因为 Cmdenv 支持批处理。Cmdenv 是一个简便的小
型命令行接口,执行速度快。它可以在所有操作系统平台上运行。Cmdenv 可以一次批处理
配置文件中所有的仿真。
1.1.2 OMNeT++结构
(1) OMNeT++具有模块化的结构,图 1 是 OMNeT++仿真的高层体系结构。
图 1 的箭头表示两组件之间的交互,图中共有 5 个箭头,表示了组件间的 5 种关系。
(1)执行模型和 Sim:仿真内核管理将来的事件,当有事件发生时,仿真内核就调用执
行模型中的模块。执行模型的模块存储在 Sim 的 main 对象中。执行模型依次调用仿真内核
的函数并使用 Sim 库中的类。
3
(2)Sim 和模型组件库:当仿真开始运行创建了仿真模型的时候,仿真内核就实例化简
单模块和其它的组件。当创建动态模块时,仿真内核也要引用组件库。实现在模型组件库中
注册和查寻组件也是 Sim 的功能。
(3)执行模型和 Envir:ev 对象作为 Envir 的一部分,是面向执行模型的用户接口。仿
真模型使用 ev 对象来记录调试信息。
(4)Sim 和 Envir:由 Envir 决定创建何种模型,Envir 包含主要的仿真循环,并调用仿
真内核以实现必须的功能。Envir 捕捉并处理执行过程中发生在仿真内核和或类库中的错误
和异常。
(5)Envir 和 Tkenv,Cmdenv:Envir 定义了表示用户接口的 TOmnetApp 基类,Tkenv
和 Cmdenv 都是 TOmnetApp 的派生类。main()函数是 Envir 的一部分,为仿真决定选用合适
的用户接口类,创建用户接口类的实例并执行。Sim 和模型对 ev 对象的调用通过实例化
TOmnetApp 类进行。Envir 通过 TOmnetApp 和其它类的方法实现 Tkenv 和 Cmdenv 的框架
和基本功能。
1.2 OMNeT++的安装
OMNeT++的安装环境:
a) Linux
b) 其他一些类似 Unix 的系统
c) Win32 平台 (NT4.0, Window 2000,XP)
本书主要讨论在 windows 平台下的仿真。
2.2 在 windows 环境下,安装前需要安装好 Visual C++ 7.0 或具有 Service Pack 6
支持的 Visual Studio 6.0;
安装步骤
(1)从官方网站:www.omnetpp.org 下载 omnetpp-3.3-win32.exe 安装包,开始安装
(2)在安装过程中,注意 vc++版本的选择。它有 vc8.0、vc.7.0、vc6.0 等选项,一般
选择 vc6.0 release。另外还有 gswin32c 路径的选择,ghostscript 主要用于打开或打
印 ps 或 pdf 图形格式的文件。
(3)安装完毕后,应该先进行环境变量的设置。即:在 vc6.0 的 bin 目录下,找到
VCVARS32.BAT 文件,然后进入 cmd 下,运行即可。
4
1.3 OMNeT++语法
OMNET++是面向对象的离散事件模拟工具,为基于进程式和事件驱动两种方式的仿
真提供了支持。 OMNET++采用混合式的建模方式,同时使用了 OMNET++特有的
ned(Network Discription,网络描述)语言和 C++进行建模。OMNET++的主要模型拓扑
描述语言 NED,采用它可以完成一个网络模型的描述。 网络描述包括下列组件:输入申明、
信道定义、网络定义、简单模块和复合模块定义。使用 NED 描述网络,产生 NED 文件,
该文件不能直接被 C++编译器使用,需要首先采用 OMNET++提供的编译工具 NEDC
将.NED 文件编译成.cpp 文件。最后,使用 C++编译器将这些文件与用户和自己设计的简
单模块程序连接成可执行程序。
2.3.1 NED 语言
1.3.1.1 NED 总概述
NED 语言用来刻画定义模型的拓扑结构,方便对一个网络的模型化描述,这意味着一
个网络的描述可以包括一组元件的描述(通道,简单/复杂模型),这些组件的描述可以在其
他网络描述中得以重用。包含网络描述的文件带有.Ned 的后缀,.Ned 文件动态地载入到模
拟程序,或者用 Ned 编译器或 C++代码链接到模拟器执行。NED 文件可以使用任何文本编
辑器或 GNED 图形编辑器来编写。
1.3.1.2 Ned 描述的组件
一个 NED 描述包括以下的组件(按任意次序排列)
(1)输入指示:用于引进其它网络描述文件,引进一个网络描述后,可以使用它所包
含的模块通道等组件,当一个文件被引进,只有声明信息是可用的,并且引进一个
D 文件并不会使该 NED 文件被编译,当父文件被 NED 编译时,例如,你可以编译
所有并连接所有的网络描述文件你可以用文件名(用 NED 扩展名也可),同样可以
在文件包括一条路径或者用 NED 编译器的
明星行选项名引进文件的路径。
如:import "ethernet"; // imports ethernet.ned
(2)信道定义:说明一个链接类型的特征,在信道申明中包含三个属性,它们都是可
5
选项的:delay(每仿真秒的传输延时),error(比特错误率),datarate(信道带宽)。
且三者出现的先后顺序没有限制。
如: channel LeasedLine
delay 0.0018 // sec
error 1e-8
datarate 128000 // bit/sec
endchannel
(3)简单模块和复合模块定义:
简单模块:它是复合模块的基本构建成分,它通过申明它的参数和门来定义。
语法如下:
simple SimpleModuleName
parameters:
gates:
//...
//...
endsimple
复合模块:它由一个或多个子模块组成。不管是简单模块还是复合模块都可以
用做子模块。它们也都能有门和参数,在简单模块能够使用的任何地方复合模
块都能使用。相对于简单模块,它还有两个部分:子模块和链接。语法如下:
module CompoundModule
parameters:
gates:
//...
//...
submodules:
//...
connections:
//...
6
endmodule
其中任意部分(参数,门,子模块,链接)都是可选项。
(4) 网络定义:模块声明只定义了模块类型,要确实地获得一个仿真器能运行的模
块,需要书写网络定义,网络定义将前面定义的模块类型声明为一个仿真模块实
例,尽管可以将一个模块作为自包含的简单模块并实例为一个网络,你可能更想使
用复合模块类型。在NED文件中可以有几个网络定义仿真程序,使用NED文件可
运行其中任何一个,你可以在配置文件时选择最想使用的那个,网络定义的语法如
下:
network wirelessLAN: WirelessLAN
parameters:
numUsers=10,
httpTraffic=true,
ftpTraffic=true,
distanceFromHub=truncnormal(100,60);
endnetwork
wirelessLAN 是前面定义好的复合模块的名称,它应该包含关于 wirelessHost,
wirelessHub 等类型进一步的复合模块的定义。自然地,只有模块类型可以使用在网
络定义中,与子模块定义一样,不需要对它所有的指针赋值。
图 2:OMNeT++中的简单模块和复合模块
7
1.3.1.3 函数
在NED表达式中,可以使用以下数学函数:
(1)C语言中库函数:exp( ),log( ),cos( ),floor( ),ceil( )等等。
(2)产生随机变量的函数:uniform, exponential, normal等等。
表达式可以包含不同类型的随机变量,指针类型(除了 const)返回不同的值,每次被
计算。如果声明为 const 类型,指针值只在仿真开始的时候计算一次,以后的访问返回相同
的值,随机变量程序用随机数字生成其中的一个,缺省为 genertor0。
函数描述如下表:
(3)用户自定义函数:
要使用用户自定义的函数,需C++代码带有0,1,2,3,4个参数(double
型),返回double型的值,函数要在C++文件中用Define_Function()macro
注册。例如:
8