基于OMNET++的tictoc仿真Word文档下载推荐.docx
《基于OMNET++的tictoc仿真Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于OMNET++的tictoc仿真Word文档下载推荐.docx(10页珍藏版)》请在冰豆网上搜索。
C++用来实现模型的仿真和消息的处理等功能。
而且NED文件可以编译为C++代码,连接到仿真程序中。
可以说,OMNeT++仿真环境是用C++实现的。
NS-2只能运行在Linux环境中,它使用OTcl和C++两种建模仿真语言,它生成的仿真程序不具备可携带性。
②可仿真模型的范围。
OMNeT++可以支持TCP/IP、SCSI和FDDI等多种协议模型,而NS-2只能支持基于TCP/IP的协议模型。
③仿真效率。
OMNeT++支持模块化仿真模型,模块可以灵活地组合,还可以多次使用。
它还支持使用参量,可以在不修改源代码和不重新编译的情况下。
直接设置参量,对不同条件下的网络模型进行仿真,因此比NS-2具有更好的仿真效率。
④仿真结果输出的性能。
OMNeT++提供强大完善
的图形用户界面,具有模块输出窗口、监测器和自动生成动画3个输出工具,可以动态地观察仿真程序的运行情况,而且内存消耗小、速度快。
也具有自动生成动画效果的功能,但没有模块输出窗口和监测器。
可以看出,MNET++具有更强大的计算机网络模型仿真能力,OMNET++更适用于各种计算机网络模型的仿真。
2、TICTOC仿真步骤
首先,让我们来考虑一个包含两个节点的“网络”,节点所做的事非常简单就是:
一个节点创建数据包,然后这两个节点将该数据包来回传送,(就像打乒乓球一样),我们把这两个节点分别称之为“tic”和“toc”。
从零开始——实现你的第一个仿真的步骤:
1.创建一个工作目录,取名tictoc,并切换到该目录。
(译者注:
路径名不能含空格和中文字符)。
2.创建一个拓扑文件来描述该样例网络。
拓扑文件是标识网络节点及其链路的文本文件,有两种编辑方式,可视化以及代码方式。
我们对它取名为tictoc1.ned:
、
3.现在我们需要实现简单模块Txc1的功能,通过写一个C++文件(txc1.cc)来完成。
在初始化函数中我们创建了一个消息对象(cMessage)并通过输出门out对外发送。
因为该门连接到其他模块的输入门,所以仿真内核将会把handleMessage()函数参数中携带的这个消息传递给其他模块。
该消息将会在NED文件中指派给链路的100ms传播延迟后到达。
其他模块收到后同样将该消息送回(仍然经过100ms的延迟),所以整个过程就像一个永不停歇的乒乓球一样。
在OMNeT++中,所有的消息(数据包、帧、任务等)和事件(定时、超时)都通过cMessage对象(或它的子类)描述。
一旦它们被送出或者被调度,就会被仿真内核放在”已调度事件”和”未来事件”列表中,直到时钟来临,再通过handleMessage()传递到相关模块。
要注意到在本仿真样例中,并没有内建停止条件,也就是说,仿真会一直进行下去。
你可以从GUI图形界面停止它。
4.使用opp_makemake命令创建Makefile文件。
Windows+msvc环境用户使用opp_nmakemake命令创建Makefile.vc文件。
5.使用make命令编译。
Windows+msvc环境用户使用nmake-fMakefile.vc命令编译。
6.创建配置文件omnetpp.ini。
该文件可以向模型中传递参数。
7.运行tictoc进行仿真
8.选定仿真的网络实例名为tictoc1,进入界面后,单击工具条中RUN按钮开始仿真。
主窗口的工具栏显示的是仿真时间,这是个虚拟时间,和程序运行的真实时间(你家墙钟记录下的)没有任何关系。
事实上,这里显示的仿真时间所对应的物理世界时间的多少更多依赖于你的硬件条件,而不是仿真模型本身的性质和复杂度。
提示到在这里的节点本地处理消息时间为零仿真时间,该模型中,仅仅只有链路传播延迟能产生仿真时间。
9.在仿真图形窗口的顶部(右上角),有一个滑动按钮,你可以通过它来控制仿真速度;
按F8停止仿真(相当于按下工具栏的STOP按钮),F4是单步执行模式,F5是连续带动画模式,F6是连续无动画模式,F7是极速模式,完全关闭跟踪特性来追求最大速度。
注意到状态栏上的event/sec和simsec/sec的量度不同(译者注:
event/sec是每秒处理的事件数,而simsec/sec是每秒所经历的仿真时间秒数,在本例中,每100ms产生一个事件,故前者刚好是后者的10倍)。
10.点击关闭图标或者选择”File”->
“Exit”来退出仿真程序。
二、改进型的两节点tictoc
1:
增强图形显示,添加调试输出
在这里,我们将做一些工作使得模型在GUI界面里更好看一些,选择”images/block”目录下的routing.png文件作为tic和toc的图标,分别涂上青色和黄色。
这个工作通过在NED文件里增加显示代码行。
”i=block/routing”代码行指示了图标文件所在的位置。
2.增加状态变量
本小节中,我们向模块添加一个计数器,并在十次的消息交换后删除消息。
把计数器作为一个类的成员:
初始化变量为10,并且在经过一次的handleMessage()处理后减1,当它变为0后,仿真
程序完成所有的事件处理并终止运行。
3.增加参数
本小节里,你将会学会如何在仿真里添加输入参数:
我们将把“神奇的数字”10作为一个参数并增加一个布尔参数来决定模块是否应该在初始化代码时发送它的第一条消息。
(不管它是一个tic还是toc模块)。
需要在NED文件里声明模块参数,数据类型可以是数字、字符串、布尔型或者xml。
现在,我们可以在NED文件或者omnetpp.ini文件里对参数进行赋值,前者优先于后者。
你也可以在NED文件里使用default(…)给参数定义一个默认值。
在这种情况下,你既可以在omnetpp.ini里设置参数值,也可以使用NED文件提供的默认值。
4.使用继承
如果我们认真查看一下NED文件就会发现其实tic和toc仅仅是在参数值和显示语句上不同而已。
我们可以通过从一个简单模块类型继承并修改它的一些参数来得到新的简单模块类型。
在本例中,我们得到了两个简单模块类型(tic和toc)。
只要在网络中定义之后,接下来我们就可以使用这些类型了。
5.建立延迟处理模型
在之前的模型里,tic和toc收到消息后都立即回传,没有处理延迟。
接下来我们将给节点增加1个仿真秒的处理延迟,然后再回传。
在OMNeT++里,通过模块给自身发送消息来这种计时。
这种消息也被称之为“自消息”。
(不同的只是这种消息的使用方式,不然它们也只是普通的消息对象)我们在类里增加两个cMessage指针变量:
event和tictocMsg,分别用来指向我们用来计时的事件消息和我们要进行仿真其延迟处理的数据包消息。
6.随机数和参数
本小节我们将介绍随机数。
把之前的延迟设为1s到一个随机数之间,该随机数可以在NED文件或者omnetpp.ini文件里设置。
模块参数也可以返回随机数变量,但是,要想使用这个功能,我们不得不在每次调用handleMessage()函数的时候去读那个参数。
7.超时和时钟中止
为了更进一步地模拟网络协议,我们把之前的模型改成一个“停-等”仿真,这次将把tic和toc的类区分开来,基本场景还是和之前类似:
tic和toc彼此来回传递消息。
但是,在非零概率下,toc将会发生丢包,这个时候我们需要重传数据包。
所以,当tic发送消息的时候,它就启动一个计时器,一旦计时器届满,就认定消息丢失了,然后重新再发一份。
如果收到toc的回复包,计时器就会被取消。
8.消息重传
在本小节理我们对之前的模型进行进一步优化。
之前在需要重传时我们就重新创建另一个数据包,当数据包比较小的时候这个是没有问题的,但在实际生活中,通常采取的措施是保留一份源拷贝,这样在重传的时候就不需要重新创建数据包。
我们在这里采取的是保留原始数据包,而把拷贝副本发送出去,当toc的应答包到来的时候,我们才删除原始包。
为了便于直观地检验该模型,我们在每个消息上增加了一个消息序列号。
9.两个以上节点组成的网络
现在我们来进行一次比较大的跨越:
创建几个tic模块并把它们连成一个网络。
它们所做的事情很简单:
其中一个节点产生一个消息,其他节点随机传送该消息,直到它到达预先指定的目标节点。
相应的NED文件需要做一些修改,首先,Txc模块必须包含多个input和output门:
方括号[]把之前的门变成了门向量,当我们用Txc来建立网络的时候,才决定其向量的大小(门数)。
在这里我们创建了一个模块向量,包含6个模块,模块连接后的拓扑如下:
在这个版本里,tic[0]将产生消息并发送给周围节点,这个是在调用初始化函数initialize()完成的,初始化函数调用getIndex()函数,该函数返回该模块在向量中的索引。
当一个消息到达节点的时候,handleMessage()函数就会调用fowwaredMessage(),获取一个随机的的门编号(编号在门向量范围内),然后从该门发送出消息。
当消息到达tic[3]时,它的handleMessage()函数将会删除这个消息。
10.信道和内部类型定义
我们刚才定义的网络显得太过复杂和冗长,特别是连接部分。
让我们试着来简化一下。
首先我们注意到基本上所有的连接都使用相同的延迟参数,可以给这些相似的连接(信道)创建类型。
我们可以创建一个信道类型来指定延迟参数,然后在网络中的所有连接上使用这种类型。
11.使用双向连接
如果我们更仔细地检查刚才的连接部分,我们可以发现每个节点对通过两个连接连在一起,每个方向各一个连接,OMNeT++提供了双向连接,我们可以使用它。
首先,我们需要定义一个双向门(inout)来取代之前的input和output门。
12.自定义我们的消息类
本小节里,目标地址不再是指定的tic[3],我们将使用一个随机的目标地址并让消息带上该地址。
最好的方法是派生cMessage子类并添加一个数据成员。
手动编码消息类通常会很冗长,因为包含很多的样板代码(boilerplatecode),所以我们让OMNeT++为我们创建这个类。
三、增加统计收集
13.显示消息收发数目
通过给模块类加入两个计数器:
numSent和numReceived,就可以在运行时记录下每个节点收发的消息数。
在离散仿真模型中,各节点的收发数目大致相同,这说明均匀分布函数intuniform()工作正常。
但是在现实仿真中你可以快速了解模型中各节点的状态,这点很有用。
14.我们可以统计仿真中的感兴趣变量。
我们将记录每条消息的跳数,并记录为向量对数据输出。
然后我们按节点统计出均值、标准差、最小值及最大值。
仿真结束时将这些值保存到文件中,以便用离线工具分析。
四、通过Plove和Scalars可视化结果
1.标量、向量输出可视化
OMNeT++IDE可以帮你分析结果数据。
它可以过滤、处理和显示向量及标量数据,当然也可以显示柱状图。
下面的图表就是IDE的结果分析工具所创建的。
上一次的模型中记录了一个消息每次到达目标节点所经历的跳数,下图显示了节点0和节点1的这些向量结果:
如果我们应用一个求均值的操作,就可看到不同节点的跳数如何趋向一个平均值:
下图显示了到达每个目标节点的消息所经历平均跳数和最大跳数,基于仿真结束后所记录的标量数据:
下图显示了跳数分布的柱状图:
2.顺序图
OMNeT仿真内核可以把仿真期间的消息交换历史记录到一个日志文件。
该文件稍后可以用顺序图工具(SequenceCharttool)进行分析。
下图是通过顺序图工具创建的,显示了消息在网络中两个不同节点之间是如何被路由转发的。
这个例子中的图标非常简单,但是当你的模型很复杂的时候,顺序图在进行调试(debugging)、探测(exploring)和记录(documenting)模型行为的时候非常有价值。