NS2与网络模拟(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-18 03:37:57

点击下载

作者:于斌,孙斌,温暖,王绘丽,陈江锋 编著

出版社:通信图书编辑部

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

NS2与网络模拟

NS2与网络模拟试读:

前言

在如今这个信息化的时代,网络几乎无处不在,它已经延伸至社会、经济、安全的每一个角落,影响着个人生活的方方面面。在网络迅速发展扩大的同时,也面临着更高的技术要求,如快速的路由协议、安全性、高带宽等。对网络本身的研究,也就成为科研领域中的一大热点,在研究过程中,受成本、环境、人工等种种因素影响,常常需要在模拟的网络环境下进行。当前的网络模拟软件种类较多,特点各异,本书中将主要介绍其中一种影响力较广、使用者较多,并且属于开源版本的优秀网络模拟软件——NS2。

全书共分为7章:第1章主要介绍NS2的背景知识及安装的操作过程;第2章通过几个简单的Tcl脚本例子,使读者对NS2的使用有个直观的认识;第3章主要介绍NS2中使用的几种开发语言,Tcl、OTcl和C++,包括命令格式、流程控制、输入输出等;第 4 章中提到的分裂对象模型,主要是解决多种编程语言之间对象和变量的关联问题;第 5 章则重点介绍了NS2这一软件的设计原理、构件、组成元素等,通过详实的例子详细剖析了软件的众多特性;第6章则介绍了NS2所使用的众多工具,正是通过这些工具,NS2才能拥有更多、更强大的功能。第7章列举了NS2在教育、科研环境下的具体应用,包括协议的增加、修改等,使读者能够进一步理解和掌握这一模拟软件。

作者长期使用NS2软件进行网络模拟,具备丰富的源代码分析和模拟实践经验。本书所讲的内容很多是作者使用NS2过程中遇到困难的解决方法。每个人遇到的困难可能不同,作者只能从自己碰到的或能预料到的方面来讲解。由于作者水平有限,书中难免存在疏漏和错误,敬请读者批评指正。作者2006年12月第1章NS2的简介和安装1.1 NS2的简介

对于如何验证网络协议的正确性和进行相关性能测试,人们提出了很多方法,目前最广泛使用的方法就是通过虚拟环境进行模拟仿真。NS2是最流行的进行网络模拟的软件之一,已广泛被科研院所和各大高校用于进行网络分析、研究和教学。它支持众多的协议,并提供了丰富的测试脚本。

NS2,即Network Simulator Version 2,是面向对象的、离散事件驱动的网络环境模拟器,主要用于解决网络研究方面的问题。NS2提供了在无线或有线网络上的TCP、路由、多播等多种协议的模拟。

NS2来源于1989年的Real Network Simulator项目,经过多年的发展,于1995年得到施乐公司(Xerox)的支持,加入VINT项目。NS2一直以来都在吸收全世界各地研究者的成果,包括UCB、CMU等大学和SUN等公司的无线网络方面的代码。

NS2是一个面向对象的网络模拟工具,可以完整地模拟整个网络环境。NS2使用一整套C++类库实现了绝大多数常见的网络协议以及链路层的模型,利用这些类的实例就可以搭建起整个网络的模型, 而且包括详尽的细节实现。这简直就是一种梦想的实现,试想如果手头能有这样一个工具,我们就可以在单机环境中模拟网络的各个元素,加深对网络的了解和认识;同时,加快我们开发新协议的速度。

与NS2类似的软件有 OPNET,这是一个商用的网络模拟软件,它能够针对各款交换机和路由器来搭建网络;与之相比,NS2是一个免费的软件,它可以在Windows/UNIX上运行,且所有源代码公开,对于进行网络的研究和扩展非常方便,所以在学术界更多的是采用NS2来做模拟。

NS2使用两种编程语言,OTcl(具有面向对象特性的Tcl脚本程序设计语言)和C++。之所以选择这两种语言,是因为模拟器有两方面的事情需要做。一方面,具体协议的模拟和实现,需要一种程序设计语言,能够高效率地处理字节(Byte)、报头(Packet Header)等信息,能够应用合适的算法在大量的数据集合上进行操作。为了实现该任务,程序内部模块的运行速度(run-time speed)是非常重要的,而运行模拟环境的时间、寻找和修复bug的时间,以及重新编译和运行的时间(run-around time)不是很重要。这种情况下,C++语言是非常合适的。另一方面,许多网络中的研究工作都是围绕着网络组件和环境的具体参数的设置和改变而进行的,需要在短时间内快速地开发和模拟出所需要的网络环境(scenarios),并且方便修改和发现、修复程序中的 Bug。在这种要求下,网络环境布置的时间就显得很重要了,因为模拟环境的建立和参数信息的配置只需要运行一次。因此,脚本语言就具有很大优势,具有面向对象特性的Tcl脚本语言可以充分满足此需求。

NS2的Tcl/C++架构与Windows下的COM/VBScript编程模式有些类似,使用VC来编写和实现COM对象,然后使用VB来操纵COM对象。Windows提供了COM接口,这就在系统范围内保证了这种机制的有效性。与之相比,NS2则能够使Tcl脚本了解到它的C++类库结构,同时按照它的类分级来创建对象,这也很了不起。

总之,NS2为我们提供了一个很好的网络模拟实验平台。同时,由于它使用两种语言,对使用者的要求也相应增高。1.2 NS2的安装

NS2是在UNIX系统上开发的,因此可以在FreeBSD、SunOS、Solaris等UNIX和类UNIX系统上安装,另外,NS2也可以安装并运行在Windows平台上,但最好在Posix-like的机器上使用。所需硬件条件,对于一般的模拟来说,只需要普通的计算机即可,而运行大的模拟场景则需要大量的内存,同时,高性能的 CPU对于提高NS2模拟速度也很关键的。软件要求方面,安装NS2需要一个C++编译器。

NS2的安装有两种方式:一次性安装(allinone软件包)和组装(from all the pieces)。用allinone软件包安装NS2需要大约320MB硬盘空间;选择组装方式进行安装则会节省一些空间。但前者安装操作更为方便、简单,所以大多使用者采用此种安装方式。1.2.1 不同平台对NS2支持情况的比较

1.支持的软件模块

NS2 的实现依赖于许多组件(软件模块),这些组件相互依赖,安装时应该按照一定的顺序进行。各平台对软件模块的支持情况如表1-1所示。表1-1 不同平台对NS2的支持情况(Y——支持,N——不支持)

2.稳定性

在PC+Windows平台上使用NS2时,可能出现的问题比较多。例如,若在Cygwin下安装NS2,那么安装完成之后会产生一个Home子目录,并且在Home目录下生成一个使用者的文件夹,放置一些环境变量等信息,这是在第一次使用Cygwin之后,根据电脑使用者的一些信息生成的。因为Cygwin认为Administrator是惟一的合法使用者,如果启动 Cygwin时发现没有Home子目录,则表示现有的用户身份不是管理员,必须重新启动Windows系统,并以Administrator身份重新登录,然后再开启Cygwin,就会看到Home子目录,同时有三个文件夹在Administrator子目录下。

NS2在PC+Linux环境下的使用情况,总的来说比较稳定,安装也比较方便,但也会出现一些由于组件安装不完全引起的问题,所以一般都需要完全安装。

3.总结和建议

综合比较各个平台对NS2的支持情况,总体情况如表1-2所示。表1-2 综合比较Windows和Linux对NS2的支持情况1.2.2 Linux平台使用allinone方式的安装过程

这是安装NS2最常用、最方便的方法,推荐使用。(1)在http://www.isi.edu/nsnam/dist/网页上下载要使用的版本。本文以2.28版本为例讲解,则需要下载ns-allinone-2.28.tar.gz。(2)假定当前用户为nsuser,当前目录为/home/nsuser/,用tar命令解压缩ns-allinone-2.28.tar.gz,如图1-1所示。图1-1 用tar命令解压缩ns-allinone_2.28.tar.gz的界面(3)将nam1.11文件夹中的agent.h文件的73行最后的null改为0,否则会编译出错,不能产生nam的运行函数。(4)进入解压出来的文件夹ns-allinone-2.28,执行./install命令,如图1-2所示。(5)NS2开始自动安装,如果最后出现如图1-3所示的画面,则说明安装结束,已经成功安装NS2。(6)退出到目录/home/nsuser,打开.bashrc文件,修改NS2提示设置的环境变量的值:PATH、LD_LIBRARY_PATH和TCL_LIBRARY,如图1-4所示。图1-2 进入ns-allinone-2.28执行./install的界面图1-3 NS2安装结束后的界面图1-4 修改3个环境变量后.bashrc文件的内容1.2.3 Windows平台Cygwin环境下的安装过程

首先要获得Cygwin软件包和NS2.28软件包,可在附加光盘中找到,也可从网上下载。

接下来先进行Cygwin的安装。解压缩cygwin.rar文件,解压后进入新生成的cygwin文件夹,点击其中的setup.exe文件开始安装Cygwin。按“下一步”,进入图1-5所示的界面。图1-5 安装Cygwin的开始界面

选择图1-5后,点击“下一步”,开始选择安装的位置,可以选择任意磁盘分区,只要有足够空间即可,如图1-6所示,我们选择安装在c盘下,其他选项不需更改。图1-6 选择安装Cygwin的位置

点击“下一步”,开始选择源文件,源文件目录就是解压生成的cygwin文件夹中名字为“ftp……”的文件夹。具体过程是先点击“Browse...”,弹出“浏览文件夹”对话框,找到解压缩得到的cygwin文件夹,选择其子目录“ftp……”,即图1-7中标注为深色的部分,点击“确定”之后,按“下一步”。图1-7 选择要安装的文件

下一界面是选取需要的安装包,点击右上角的“View”按钮,旁边的“Category”会变为“Full”字样,如图1-8、图1-9所示。图1-8 选择需要的数据包(一)

再点击“New”这一栏所有的“Skip”,选择全部安装,这样避免在今后使用 NS2 中的风险。要注意的是,“Skip”被点击后,会变成一个版本号似的数字序列,如:2.6-1 或年月日之类的,而且“Bi..”这一列的显示信息会由n/a变成。单击完所有的“Skip”后,按“下一步”。图1-9 选择需要的数据包(二)

然后就进入安装界面,这里时间会稍微长些,要耐心等待。全部安装完了以后,单击“完成”即可。

最后弹出对话框,单击“确定”,cygwin就安装完毕了。

然后我们开始进行NS2的安装。

先首次运行 Cygwin(可以单击桌面上生成的快捷方式,图标为),系统会自动在C:\cygwin文件夹中生成\home\×××文件夹(其中×××为当前windows的登录名,注意登录名中间不能存在空格,否则将无法成功安装NS2)。

然后将ns-allinone-2.28.rar文件解压缩到\home\×××下。

解压缩结束后,运行Cygwin。之后变换路径,输入:cd ns-allinone-2.28/NS2.28/回车,如图1-10所示。图1-10 变换路径

然后输入./configure; make clean; make按回车,如图1-11所示。图1-11

当看到图1-12所示的界面时,就表示安装完成了。图1-12 安装完成NS2的界面

此时可以输入ls ns.exe验证一下,如果系统中安装有NS2软件,则显示ns.exe。

在使用NS2之前还有一个步骤要做,将解压缩得到的cygwin文件夹中的.bashrc文件拷贝到c:/cygwin/home/×××文件夹下,覆盖原有的文件,再将nam-1.11中的nam.exe文件和NS2.28中的ns.exe文件拷入待运行的tcl脚本存储的地方。在此,我们用NS2提供的示例来说明一下,将上两个文件存入~/ns-tutorial/example 下,然后开始运行 example 脚本,操作如图1-13所示。

输入:cd ns-tutorial/example/回车

输入:ls回车,即可显示文件夹内的示例

输入:startxwin.bat启动Cygwin/X server窗口

在窗口中输入ns example2.tcl回车,如果弹出nam窗口,表示可以正常使用。1.2.4 VMware虚拟机环境下的安装过程

此种使用方式主要是针对某些用户的需求。利用虚拟机,可以在Windows平台下搭建Linux系统,然后再安装NS2软件,使用过程中能够在双操作系统中自由切换,适合既要求NS2方便、稳定,又不太熟悉Linux平台的用户。下面主要介绍一下应用较广、使用较方便的虚拟机——VMware。

在VMware官方网站下载VMware Workstation的试用版本,申请注册码之后,可以获得30天的使用时间。在 Windows系统(宿主机)安装 VMware 的过程较为简单,按照提示点击即可。安装完后,运行VMware,然后安装Linux操作系统(客户机)。之后,NS2的安装可以参照、选择前面介绍的安装方式,使用方法也相同。图1-13第2章NS2初级入门

安装NS2之后,就可以运行软件了。NS2有两种运行方式,第一种是“脚本方式”,输入命令:ns tclscripl.tcl,其中tclscripl.tcl是一个Tcl脚本的文件名字,在这个文件中定义了整个模拟的过程,包括网络的拓扑结构以及数据的收发过程等内容;第二种是“命令行方式”,输入命令:ns,进入NS2的命令行环境,然后直接输入各种指令来交互式地运行NS2。

运行NS2以后也有两种方法记录结果,第一种是记录在trace文件中,即生成一个××.tr的trace文件,文件中记录了整个模拟过程的数据;第二种是由 nam体现出来,nam是一个动画演示程序。只要在执行NS2时产生了nam-trace文件,即××.nam文件,就可以在NS2模拟结束后,通过nam演示整个模拟过程。

下面我们通过对三个例子的简单分析来初步了解NS2和Tcl脚本。2.1 第一个Tcl脚本

本节将介绍如何写一个最简单的Tcl脚本。首先新建一个名为example1.tcl的文件。然后将下面的内容添加到example1.tcl文件中,这样就写好了一个Tcl脚本(第一列为行号,并非文本本身的内容,只是为方便阅读而加上去的,下同)。 1 set ns [new Simulator] 2 set tracef [open example1.tr w] 3 $ns trace-all $tracef 4 set namtf [open example1.nam w] 5 $ns namtrace-all $namtf 6 proc finish {}{ 7 global ns tracef namtf 8 $ns flush-trace 9 close$tracef 10 close$namtf 11 exec nam example1.nam& 12 exit 0 13 } 14 set n0 [$ns node] 15 set n1 [$ns node] 16 $ns duplex-link $n0 $n1 1Mb 10ms DropTail 17 set udp0 [new Agent/UDP] 18 $ns attach-agent $n0 $udp0 19 set cbr0 [new Application/Traffic/CBR] 20 $cbr0 set packetSize_ 500 21 $cbr0 set interval_ 0.005 22 $cbr0 attach-agent $udp0 23 set null0 [new Agent/Null] 24 $ns attach-agent $n1 $null0 25 $ns connect $udp0 $null0 26 $ns at 0.5 “$cbr0 start” 27 $ns at 4.5 “$cbr0 stop” 28 $ns at 5.0 “finish” 29 $ns run

下面简单介绍各行语句的作用:

第1行:建立一个新的模拟对象simulator;

第2~5行:设定变量tracef指向example1.tr文件,example1.tr文件用来记录模拟过程的trace数据;设定变量namtf指向example1.nam文件,example1.nam文件用来记录nam的trace数据;

第6~13行:建立一个名为finish的过程,用来关闭两个trace文件,并在模拟结束后调用nam程序;

第14~15行:新创建两个节点n0和n1;

第16行:在n0和n1之间建立一条双向的链路,设定链路的带宽为1Mbit/s、时延为10ms、队列类型为DropTail;

第17~18行:创建一个UDP Agent,并将其绑定到n0节点上;

第19~22行:创建一个CBR(Constant Bit Rate)流量发生器,设定分组的大小为500B,发送间隔为5ms,然后将其绑定到udp0上;

第23~24行:创建一个Null Agent,并将其绑定到n1上;Null是一种数据接收器,负责接收CBR发送的数据;

第25行:将udp0和null0这两个Agent连接起来;

第26~27行:告知simulator对象在0.5s时启动cbr0,即开始发送数据,在4.5s时停止cbr0,即停止发送数据;

第28行:告知simulator对象在5.0s时调用finish过程;

第29行:开始模拟。

写好上述Tcl脚本后,输入命令“ns example1.tcl”来运行这个脚本,程序会自动调用nam演示模拟的过程。用户只需点击nam窗口中的播放按钮,就可以看到整个模拟的过程,如图2-1所示。可以在 nam窗口中点击运动中的数据包,查看该数据包的属性,还可以点击两点间的链路,查看链路的参数设置是否和写入的Tcl脚本相同。另外,用户可以改变example1.tcl脚本中设定的一些变量值,如“packetsize_”、“interval_”等,观察模拟发生的变化。图2-1 用nam演示example1.tcl的运行结果

模拟结束后,在保存example1.tcl文件的目录中会生成example1.tr和example1.nam两个文件。example1.nam是为nam程序生成的模拟记录,nam程序读取其内容来演示整个模拟过程。example1.tr是用来记录整个模拟过程数据的,我们可以通过分析此文件来了解模拟过程。下面是example.tr的一个片断: + 3.69 0 1 cbr 500 -------- 0 0.0 1.0 638 638 - 3.69 0 1 cbr 500 -------- 0 0.0 1.0 638 638 r 3.694 0 1 cbr 500 -------- 0 0.0 1.0 636 636

其中最后一行表示节点1在3.694s收到一个从节点0发出的包,包的长度为 500B,是cbr分组。更多trace文件的介绍请见本书第5章。2.2 第二个Tcl脚本(无线模型)

本节将介绍如何模拟一个简单的无线场景。和前面一样,先要创建一个wireless.tcl文件,然后将下列内容写入其中,则准备好了一个模拟无线场景的Tcl脚本。 ================================================================ # Define options ================================================================ 1 set val(chan) Channel/WirelessChannel ;#channel type 2 set val(prop) Propagation/TwoRayGround ;#radio-propagation model 3 set val(netif) Phy/WirelessPhy ;#network interface type 4 set val(mac) Mac/802_11 ;#MAC type 5 set val(ifq) Queue/DropTail/PriQueue ;#interface queue type 6 set val(ll) LL ;#link layer type 7 set val(ant) Antenna/OmniAntenna ;#antenna model 8 set val(ifqlen) 50 ;#max packet in ifq 9 set val(nn) 2 ;#number of mobilenodes 10 set val(rp) AODV ;#routing protocol 11 set val(x) 500 ;#X dimension of the topography 12 set val(y) 500 ;#Y dimension of the topography ================================================================ # Main Program ================================================================ # Initialize Global Variables 13 set ns [new Simulator] 14 set tracefd [open wireless.tr w] 15 $ns trace-all $tracefd 16 set namtracefd [new wireless.nam w] 17 $ns namtrace-all-wireless $namtracefd $val(x) $val(y) # set up topography object 18 set topo [new Topography] 19 $topo load_flatgrid $val(x) $val(y) # # Create God # 20 create-god $val(nn) # # Create the specified number of mobilenodes[$val(nn)]and"attach"them # to the channel. # Here two nodes are created:node(0)and node(1) # configure node 21 $ns node-config-adhocRouting$val(rp)\ 22 -llType$val(ll)\ 23 -macType$val(mac)\ 24 -ifqType$val(ifq)\ 25 -ifqLen$val(ifqlen)\ 26 -antType$val(ant)\ 27 -propType$val(prop)\ 28 -phyType$val(netif)\ 29 -channelType$val(chan)\ 30 -topoInstance$topo\ 31 -agentTrace ON\ 32 -routerTrace ON\ 33 -macTrace OFF\ 34 -movementTrace OFF 35 for{set i 0}{$i<$val(nn)}{incr i}{ 36 set node_($i)[$ns node] 37 $node_($i)random-motion 0 ;#disable random motion 38 } # # Provide initial (X,Y, for now Z=0) co-ordinates for mobilenodes # 39 $node_(0) set X_ 5.0 40 $node_(0) set Y_ 2.0 41 $node_(0) set Z_ 0.0 42 $node_(1) set X_ 390.0 43 $node_(1) set Y_ 385.0 44 $node_(1) set Z_ 0.0 # # Now produce some simple node movements # Node_(1) starts to move towards node_(0) # 45 $ns at 5.0 "$node_(1) setdest 25.0 20.0 15.0" 46 $ns at 1.0 "$node_(0) setdest 20.0 18.0 1.0" # Node_(1) then starts to move away from node_(0) 47 $ns at 10.0 "$node_(1) setdest 490.0 480.0 15.0" # Setup traffic flow between nodes # TCP connections between node_(0) and node_(1) 48 set tcp [new Agent/TCP] 49 $tcp set class_ 2 50 set sink [new Agent/TCPSink] 51 $ns attach-agent $node_(0) $tcp 52 $ns attach-agent $node_(1) $sink 53 $ns connect $tcp $sink 54 set ftp [new Application/FTP] 55 $ftp attach-agent $tcp 56 $ns at 1.0 "$ftp start" # # Tell nodes when the simulation ends # 57 for {set i 0} {$i < $val(nn) } {incr i} { 58 $ns at 15.0"$node_($i)reset"; 59 } 60 $ns at 15.0 "stop" 61 proc stop {} { 62 global ns tracefd namtracefd 63 $ns flush-trace 64 close$tracefd 65 close$namtracefd 66 exec nam wireless.nam& 67 exit 0 68 } 69 $ns run

下面简单介绍各行语句的作用:

第1~12行:设定模型的一些必须属性,如移动节点的Channel类型、MAC层协议、队列类型以及场景大小、节点数目等;

第13行:建立一个Simulator的实例对象,赋值给ns;

第14~17行:打开一个名为 wireless.tr的文件,用来记录模拟过程的trace数据,设置变量tracefd指向该文件;打开一个名为wireless.nam的文件,用来记录nam的trace数据,设置变量namtracefd指向该文件;

第18行:建立一个Topography对象,该对象可以保证节点在拓扑边界范围内运动;

第19行:设定模拟所用场景的大小;

第20行:建立一个God对象,主要用来对路由协议做性能评价;它存储了节点的总数、各个节点间最短路径表等信息,这些信息通常是在模拟开始前就计算好的;节点的MAC对象会调用God对象,因此即使我们在这里并不使用God对象,仍然需要建立一个God对象;

第21~34行:在建立节点之前,需要先配置节点的参数;将最初设定的模拟属性赋给节点;

第35~38行:建立两个移动节点,关闭节点的随机运动功能,即节点的运动完全由Tcl脚本设定;

第39~44行:设定两个移动节点的初始位置,即设置x轴、y轴和z轴的坐标;

第45~47行:设定两个移动节点的运动速度和运动方向,例如,第45行表示节点1在第5s的时候开始以15m/s的速度向坐标(25.0,20.0)的点运动;

第48~56行:建立一个由节点0到节点1的TCP连接,并在其上建立一个FTP数据流,该数据流从1.0s开始工作;

第57~59行:在模拟结束前调用各个移动节点的reset函数;

第60行:告知simulator对象在15.0s时调用stop过程;

第61~68行:建立一个名为stop的过程,用来关闭两个trace文件,并调用nam程序演示模拟过程的动画;

第69行:开始模拟。

写好上述Tcl脚本程序后,输入命令“ns wireless.tcl”运行该脚本,程序会自动调用nam来演示模拟的过程。用户只需点击nam窗口中的播放按钮,就可以看到整个模拟的过程。如图2-2和图2-3所示。同样也可以点击运动中的数据包查看其属性。用户还可以改变wireless.tcl脚本中设定的节点运动速度、初始位置、运动目的地等数值,观察模拟的变化,体会各属性的意义。

模拟结束后,会发现在保存wireless.tcl文件的目录下生成了wireless.tr和wireless.nam两个文件,两者的作用和上一模拟生成文件相同,但由于是无线网络模拟,其trace文件格式有所不同,下面是wireless.tr的一个片断: 1 s 12.941172739_1_RTR ---4 message 32[0 0 0 0] ------- [1:255-1:255 32 0] 2 r 12.942485197_0_RTR ---4 message 32[0 ffffffff 1 800] -------[1:255-1:255 32 0] 3 s 12.942485197_0_RTR ---1 tcp 80[0 0 0 0] ------- [0:0 1:0 32 1][0 0]0 0 4 s 12.942485197_0_RTR ---3 tcp 80[0 0 0 0] ------- [0:0 1:0 32 1][0 0]0 0 5 D 12.942485197_0_IFQ ARP 1 tcp 80[0 0 0 800] -------[0:0 1:0 32 1][0 0]0 0 6 r 12.948305406_1_AGT ---3 tcp 80[13a 1 0 800] ------- [0:0 1:0 32 1][0 0]1 0 7 s 12.948305406_1_AGT ---5 ack 40[0 0 0 0] ------- [1:0 0:0 32 0][0 0]0 0图2-2 用nam演示“wireless.tcl”的运行结果图2-3 节点的路由程序发送路由请求时的演示

举例来说,第7行表示,在第12.948305406s时节点1的AGT层发出了一个长度为40byte、编号为5的ACK分组。更多关于trace文件的细节请参见第5章。2.3 第三个Tcl脚本

从第二个例子中可以看出,每个无线节点都要在 Tcl脚本中进行初始位置、运行方向和运行时间等的设定操作。如果要模拟一个节点很多、运行轨迹很复杂的无线网络,工作量将会非常大。针对此种环境,可以通过引用的方式将节点的位置信息和运动信息添加到 Tcl 脚本中,减少工作量。举例如下: #================================================================= # Define options #================================================================= 1 set val(chan) Channel/WirelessChannel 2 set val(prop) Propagation/TwoRayGround 3 set val(netif) Phy/WirelessPhy 4 set val(mac) Mac/802_11 5 set val(ifq) Queue/DropTail/PriQueue 6 set val(ll) LL 7 set val(ant) Antenna/OmniAntenna 8 set val(x) 670 ;#X dimension of the topography 9 set val(y) 670 ;#Y dimension of the topography 10 set val(ifqlen) 50 ;#max packet in ifq 11 set val(seed) 0.0 12 set val(adhocRouting) DSR 13 set val(nn) 3 ;#how many nodes are simulated 14 set val(cp) "../mobility/scene/cbr-3-test";#数据流文件的名称及存储地址 15 set val(sc) "../mobility/scene/scen-3-test";#场景文件的名称及存储地址 16 set val(stop) 400.0 ;#simulation time # ================================================================= # Main Program # ================================================================= # # Initialize Global Variables # # create simulator instance 17 set ns_ [new Simulator] # setup topography object 18 set topo [new Topography] # define topology 19 $topo load_flatgrid $val(x) $val(y) # create trace object for ns and nam 20 set tracefd [open wireless1-out.tr w] 21 set namtrace [open wireless1-out.nam w] 22 $ns_ trace-all $tracefd 23 $ns_ namtrace-all-wireless $namtrace $val(x) $val(y) # # Create God # 24 set god_ [create-god $val(nn)] # # define how node should be created # #global node setting 25 $ns_ node-config -adhocRouting $val(adhocRouting) \ 26 -llType$val(ll)\ 27 -macType$val(mac)\ 28 -ifqType$val(ifq)\ 29 -ifqLen$val(ifqlen)\ 30 -antType$val(ant)\ 31 -propType$val(prop)\ 32 -phyType$val(netif)\ 33 -channelType$val(chan)\ 34 -topoInstance$topo\ 35 -agentTrace ON\ 36 -routerTrace OFF\ 37 -macTrace OFF # # Create the specified number of nodes[$val(nn)]and"attach"them # to the channel. 38 for {set i 0} {$i < $val(nn) } {incr i} { 39 set node_($i)[$ns_node] 40 $node_($i)random-motion 0 ;#disable random motion 41 } # # Define node movement model # # puts "Loading connection pattern..." 42 source $val(cp) # # Define traffic model # # puts "Loading scenario file..." 43 source $val(sc) # Define node initial position in nam 44 for {set i 0} {$i < $val(nn)} {incr i} { # 20 defines the node size in nam, must adjust it according to your scenario # The function must be called after mobility model is defined 45 $ns_initial_node_pos$node_($i)20 46 } # # Tell nodes when the simulation ends # 47 for {set i 0} {$i < $val(nn) } {incr i} { 48 $ns_at$val(stop).0"$node_($i)reset"; 49 } 50$ns_at $val(stop).0002"puts\"NS2 EXITING...\";$ns_halt" 51 $ns_ run

这是一个改进过的无线模拟Tcl脚本,第42行表示,从"../mobility/scene/cbr-3-test"文件中读取数据流文件;第 43 行表示,从"../mobility/scene/scen-3-test"读取场景文件。两个文件具体内容如下。

../mobility/scene/scen-3-test文件的代码:4.000000000000" $node_(0) set X_ 768.131922589676 $node_(0) set Y_ 926.529774640934 $node_(0) set Z_ 0.000000000000 $node_(1) set X_ 349.535946664184 $node_(1) set Y_ 43.714376419650 $node_(1) set Z_ 0.000000000000 $node_(2) set X_ 499.911317136097 $node_(2) set Y_ 934.754598855392 $node_(2) set Z_ 0.000000000000 $ns at 0.000000000000 "$node_(0) setdest 768.131922589676 926.529774640934 0.000000000000" $ns at 0.000000000000 "$node_(2) setdest 634.633037091528 1274.868585762972 4.000000000000" $ns at 0.000000000000 "$node_(1) setdest 349.535946664184 43.714376419650 0.000000000000" $ns at 91.456091212504 "$node_(2) setdest 509.390403753794 156.587799618294 $ns at 113.707938490641 "$node_(0) setdest 1219.488656483353 982.645932576920 0.000000000000" $ns at 325.280489910675 "$node_(1) setdest 343.215657092266 955.717747079077 4.000000000000" ../mobility/scene/cbr-3-test 文件的代码: set udp0 [new Agent/UDP] $ns attach-agent $node_(0) $udp0 set cbr0 [new Application/Traffic/CBR] $cbr0 attach-agent $udp0 $cbr0 set packetSize_ 64 $cbr0 set interval_ 0.1 set null0 [new Agent/Null] $ns attach-agent $node_(1) $null0 $ns connect $udp0 $null0 $ns at 1.0 "$cbr0 start" set udp1 [new Agent/UDP] $ns attach-agent $node_(2) $udp1 set cbr1 [new Application/Traffic/CBR] $cbr1 attach-agent $udp1 $cbr1 set packetSize_ 64 $cbr1 set interval_ 0.1 set null1 [new Agent/Null] $ns attach-agent $node_(1) $null1 $ns connect $udp1 $null1 $ns at 1.0 "$cbr1 start"

通过这种引用方式保证了Tcl脚本的简洁、方便。还有一个好处是,可以借助一些第三方软件自动生成部分代码,如设置节点的初始位置、运行轨迹以及生成节点间数据流等。关于这些附加软件的介绍见第6章。第3章NS2使用的语言简介

NS2是一个事件驱动的模拟软件。它底层的模拟引擎主要由C++编写,同时利用麻省理工学院(MIT)的面向对象的工具命令语言(OTcl)作为模拟时的命令和配置接口语言。网络模拟的全过程由一段 OTcl的脚本来描述,并被NS2解释器所解释。脚本通过调用引擎中各类的属性、方法从而定义网络的拓扑,配置数据源,目的端,建立连接,产生所有事件的时刻表,运行并跟踪模拟结果,还可以对结果进行相应的统计处理或制图。因此,NS2模拟环境中主要有两种分工不同的开发语言,OTcl和C++。

OTcl是加上面向对象特性的 Tcl,开发于MIT。Tcl读音为‘tickle’,全称是‘Tool Command Language’。Tcl是一种解释执行的脚本语言,可以在众多平台上运行。它依赖于内部的C函数库。在需要扩充Tcl命令和功能时,只需要添加新的C函数即可,扩展性很好。Tcl另一个特点是它只有字符串一种存储类型,所有的变量包括整形变量、浮点变量等都是以字符串的形式存储。Tcl解释器分为两部分,Parser和Executer。在运行指令时,Tcl的解释器先用 Parser将指令分析成多个有意义的字符串,然后用Executer执行指令,最后以字符串的形式返回结果。Tcl的特点使得OTcl类型简单,语法简单,易于修改。OTcl脚本语言可以用于处理网络场景、协议配置和程序控制等经常需要改动的地方,适合于上层的用户掌控。

C++程序运行速度快,并且可以设计精确、复杂的算法,可以用于模拟各种网络协议,适合于底层的实现。OTcl和C++都是面向对象的,可以自由地相互调用,这是通过一种称为TclCL工具包实现的。这就是NS2中的分裂对象模型,我们将在第4章中具体介绍,本章则主要讲解Tcl和OTcl脚本语言。3.1 Tcl简介

Tcl在NS2中主要是用来描述脚本,即描述模拟的网络环境和参数设定等。本节主要介绍Tcl的基本语法。

Tcl语言在大体上和C语言很相似。例如,循环结构、函数定义和数学表达式、条件表达式。但是Tcl在等式赋值和数组结构这两点上,有其自身的特点,需要读者注意。3.1.1 基本命令格式

Tcl的基本语法为:command arg1,arg2,arg3…

Tcl解释器读入每个单词,Parser将每个单词分开。第一个单词“command”就代表命令名称或者 Tcl 过程。而接下来的单词作为此命令或者过程的参数,执行此命令或者过程时调用。例如: set a “Hello World!”

在这个例句中,解释器读入三个单词,‘set’、‘a’和‘Hello World!’。set作为命令名称,告诉解释器,定义一个变量‘a’,并且赋值为‘Hello World !’。3.1.2 变量和变量赋值

Tcl语言使用变量时,不需要像C语言一样事先声明。Tcl变量是在第一次使用set指令对其赋值时产生。使用变量值时,需在变量名称前加$符号。 Example 1: set a “Hello World!” puts “NS2 say$a” 输出:NS2 say Hello World!

说明:程序第一行把“Hello World!”这个字符串赋值给变量a(Hello World!用双引号括起来后当一个字符串处理)。程序第二行使用 puts 命令把后面参数显示出来,其中会先把$a替换成Hello World!,所以屏幕上显示结果为NS2 say Hello World! Example 2: set day 18 set month 10 set year 2006 set date “$year-$month-$day” puts $date 输出:2006-10-18

说明:在程序的第四行中,$year, $month, $day分别被2006,10,18代替,然后由set指令赋值给date。 Example 3: set b “puts hi” eval $b 输出:hi

说明:变量b的值是一个Tcl脚本,第二行程序中的$b替换为puts hi,作为命令eval的参数。eval命令主要是用于执行Tcl脚本,所以显示结果为hi。3.1.3 字符串

当需要将一个字符串赋值给一个变量时,需要将其用“”括起来作为一个单词赋值。例如: set str “This is a string” puts “The string is: $str” puts “The length of the string is: [string length $str]” puts“The character at index 3 is:[string index$str 3]” puts“The characters from index 4 though 8 are:[string range$str 4 8]” puts“The index of the first occurrence of letter\”i\”is:[string first i$str]” 输出:The string is:This is a string The length of the string is:16 The character at index 3 is:s The characters from index 4 through 8 are:is a The index of the first occurrence of letter“i”is:2

说明:string length $str可以用来显示字符串的长度,string index $str 3可以用来显示字符串的第四个字母(第一个字母的index为0),string range $str 4 8可以用来显示字符串中第五个到第九个字母,string first i $str可以用来显示字母i在字符串中第一次出现的index值,也就是第一次出现在第(index+1)个位置。3.1.4 表达式

Tcl 包含很多种类的表达式,如数学表达式、关系表达式等。而这些表达式一般都使用expr这个指令来求数学表达式的值或者判断关系表达式的真假。 Example 1: set value [expr 0==1] puts $value 输出:0

说明:使用expr来判断0==1是否成立,结果假,所以把0存入value变量中。 Example 2: set value [expr 2+3] puts $value 输出:5

说明:使用expr求2+3表达式的值,并把所得到的值5存入变量value中。3.1.5 指令替代

就像变量替换一样,指令替代可以把“tcl脚本的执行结果”取代“tcl脚本”。 Example 1: puts“I am[expr 10*2]years old,and my I.Q.is[expr 100-25]” 输出:I am 20 years old, and my I.Q. is 75

说明:[]可以用来达成指令替代,所以在执行此行脚本时,会先执行[expr 10×2]和[expr 100-25]并把结果20和75取代原本脚本中的[expr 10×2]和[expr 100-25]的位置,最后再使用puts把这个字符串显示出来。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载