NS是由UC Berkeley大学开发的,来源于1989年的Real Network Simulator项目,通过多年发展,全世界各地研究者在此基础上不断综合和完善,NS已经成为一个涉及网络各个方面的优秀的网络模拟工具。因为NS是一款免费的软件,源码公开,所以,学术界使用NS研究和开发协议进行网络行为模拟和性能仿真的人员较多,每一年在国内外发表的欲望了技术相关的学术论文中,利用NS给出模拟结果的文章很是多,所以,经过这种方法得出的研究结果也被学术界广泛承认。前端
NS是一个面向对象的、离散时间驱动的模拟器。使用C++和OTcl(面向对象的Tcl语言)做为开发语言。选择这两种语言进行开发,主要基于以下考虑:1.网络协议模拟和实现须要高效的处理协议报头信息,进行大量的数据处理,所以,程序内部模块的运行速度相当重要,C++快速高效的特色很是适合于这部分工做;2.网络模拟围绕着网络组件、拓扑结构和其余环境参数而进行,参数须要快速改变以实现不一样场景的网络模拟,此时,网络环境的配置(例如模拟时间、拓扑结构和节点类型等)就显得很是重要,面向对象的OTcl脚本语言的灵活性就充分体现了优点。bash
Ubuntu上NS必要工具和库文件安装网络
1. 编译gcc、make:sudo apt-get install build-essential架构
2. tk、tcl的库文件:框架
sudo apt-get install tcl8.4ide
sudo apt-get install tcl8.4-dev函数
sudo apt-get install tk8.4工具
sudo apt-get install tk8.4-dev性能
3. 与nam相关的库文件:sudo apt-get install libxmu-dev学习
1. 下载NS安装压缩包ns2-allinone-2.29.tar.gz
2. 解压:tar –vxzf ns-allinone-2.29.tar.gz
3. 开始安装:cd /$yourpath/ns/ns-allinone-2.29/ns-2.29/.install($yourpath是你放ns安装包位置,后面假设是在/home/ns2)
4. 配置环境变量
5. 测试:在终端输入ns,若是屏幕输出%,则代表安装成功。
安装完毕后,还要修改用户目录(包括我的用户/home下面,和root用户/root下面)下的.bashrc,必须在该文件末尾追加如下3句代码(这里假定安装的是ns2.29)
export PATH=$PATH: /home/ns2/ns-allinone-2.29/bin: /home/ns2/ns-allinone-2.29/tcl8.4.11/unix: /home/ns2/ns-allinone-2.29/tk8.4.11/unix
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH: /home/ns2/ns-allinone-2.29/otcl-1.11: /home/ns2/ns-allinone-2.29/lib
export TCL_LIBRARY = /home/ns2/ns-allinone-2.29/tcl8.4.11/library
设置环境变量是为了设置NS的路径和其执行过程当中须要使用的库文件的路径。
前面提到NS使用OTcl和C++两种语言结合工做,其中OTcl是解释执行语言,C++是编译执行语言,NS实例化一个组件会同时建立一个OTcl类对象和一个对应的C++类对象(节点除外),这两个类互称为影像类,两个对象互称为影像对象,能够互操做。这就是NS的分裂对象模型——将对象分裂为两部分进行描述。
基于分裂对象的模型,NS采用两级体系结构。NS的后台描述事件调度器和大部分基本的网络组件对象,主要功能是实现对数据分组的处理,使用C++实现和编译,称为编译层次;NS的前端主要功能是堆模拟环境的创建和配置,用一个OTcl解释器对脚本进行解释,执行相应的操做,称为解释层次。NS中编译类对象经过OTcl链接创建与之对应的解释类对象,这样用户就可以方便对C++对象的函数进行修改和配置。理解这两层次之间关系对NS学习有很大帮助。
互为影响类的对象和变量是经过NS中特有的一种称为TclCL的机制关联的,在NS的架构中,TclCL支撑了整个框架——NS的类库都是创建于TclCL基础上的,共包含6个:Tcl、TclObject、TclClass、TclCommand、EmbeddedTcl和InstVar。
不少资料把NS描述为“本质上是一个离散事件模拟器”,这是由于NS的核心是离散事件驱动调度机制。事件驱动,指的是触发一个事件,而后执行相应的动做。离散事件驱动模型特色是只关注事物的状态变化(即事件),不关心变化的过渡过程。模型靠每个事件引起其余事件的方式来维持运转。每一个事件都有发生时间,模型的运转实际就是按事件发生时间顺序逐个处理事件,处理过程当中将产生新的事件。系统时间就是当前事件的发生时间,它不是等间隔变化而是跳跃变化的。
基于这种思想,NS设立了事件调度器(Scheduler),Scheduler接收来自Network Object(好比说各个层)产生的事件,并插入事件链表(一个FIFO队列),事件调度器计算仿真事件,当触发某个事件发生的时间到达时,Scheduler会激活事件队列中的事件,把事件取出并调用相应的函数进行处理。全部经由调度器调度的事件完成时间是由NS自己的一个虚拟时钟所控制的,虚拟时钟能够将实际的时间尺度放大,例如实际时间上1ms完成的事件用代码来仿真可能须要5s,因为虚拟时钟的做用,在NS中5s的时长被当作1ms来使用(这至关于在虚拟时钟上的1ms就是实际的5s,即放大功能)。因此,NS的每一层对分组封包的处理是不会在虚拟时钟内的刻度尺上刻画的,刻画刻度尺的是在调度器中规定的事件的前后时间差(这句有点抽象,不理解就忽略吧)。能够想象NS的虚拟时钟内有一个滚轴,驱动虚拟时钟滚轴滚动的就是事件调度,在本次事件调度未完成以前,滚轴不会向前滚动,而只要本次事件调度完成,就会滚动去执行下一个调度事件。须要在同一时间触发的事件将会以进入调度队列的前后顺序而被一次执行,尽管执行有前后,但NS认为它们是同一时间执行的,所以,在执行这些事件的时候,时钟的滚轴不会滚动,在跟踪文件上显示这些事件的发生时间也是相同的。
因为采用了离散时间模拟的机制,在仿真中不用考虑实际系统中须要考虑的实时性问题,这是对模拟的一种简化,能够凸显事件之间的前后顺序和接触对事件存在依赖的事件间的耦合。