计算机网络实验ns2实验

时间:2023-01-24 08:14:25

网络仿真器NS2的配置与应用


这个实验环境配置很麻烦,但是实验内容很简单......

配置环境一上午,实验只要十分钟...... 


1.        实验要求

安装并运行网络仿真器NS2,了解其功能模块及配套工具的使用,掌握利用NS2进行网络仿真的方法,为进一步的网络系统性能分析设计创造良好的条件。

 

2.        实验条件

硬件:一台计算机

软件:Ubuntu操作系统、NS2工具包

 

3.        实验指导

1)        NS2仿真流程

采用NS2进行仿真实验之前,必须先掌握本书7.2.1节中的相关内容。一般来说,采用NS2进行仿真大致可分为3个步骤:

●建立Networkmodel:描述整个网络的拓扑、带宽等信息。

●建立traffic model:描述所有的网络流量或错误情况的时间、类型、或呈何种数学分布。

●追踪分析结果:仿真完成后,可调用nam观察整个仿真流程,或是将namfile中的信息抽取出来加以分析。

 

下面是一些具体的实现语句,其中#后的说明为该语句的相关注释。(根据本人测试运行,最好文件中不要加注释,否则会报错)

a)        建立Networkmodel

●建立ns对象

 set ns[new Simulator]

 

●建立节点

 set n0[$ns node]

 

●建立连接

 $ns duplex-link $n0 $n1 <bandwidth><delay><queue_type>

队列(queue)是保持(held)或丢弃(drop)数据包的地方,目前NS2所支持的队列缓冲管理机制有drop-tail(FIFO)队列、RED缓冲管理、公平队列(Fair Queueing,FQ)、随机公平队列(StochasticFair Queueing,SFQ)、DRR(Deficit Round-Robin)和基于类的队列(class-based queuein,CBQ)。

 

●建立局域网

 $ns make-lan <node_list><bandwidth><delay>LLQueue/DropTail MAC/802.3 Channel

若只想建立点对点的网络,则无需建立局域网这个步骤。

 

b)        建立Trafficmodel

建立连接

根据不同的流量类型,可分为

TCP连接

set tcp[new Agent/TCP]          #建立TCP代理,用以产生流量

set tcpslink[new Agent/TCPSink]   #建立TCPSink代理,用以接收流量

$ns attach-agent $n0 $tcp        #将所建立的tcp配置给节点n0

$ns attach-agent $n1 $tcpsink     #将所建立的tcpsink配置给节点n1

$ns connect $tcp $tcpsink        #连接

 

UDP连接

set udp[new Agent/UDP]          #建立UDP代理,用以产生流量

set null[new Agent/NULL]         #建立NULL代理,用以接收流量

$ns attach-agent $n0 $udp        #将所建立的udp配置给节点n0

$ns attach-agent $n1 $null        #将所建立的null配置给节点n1

$ns connect $udp $null           #连接

 

●产生流量

对应TCP连接,产生FTP(or Telnet)流量:

set ftp[new Application/FTP]

$ftp attach-agent $udp

 

●建立排程

$ns at<time><event>             #<event>为任何合法的ns/tcl命令

$ns run

 

c)        追踪分析结果

$ns namtrace-all[open test.nam w]

其中test.nam为记录仿真过程的输出文件,内容包含网络的拓扑(node、link、queues、…),以及所有数据包的信息。用户可以使用该文件中的有关数据包的信息来作一些追踪分析。

 

 

2)        NS2仿真示例—nam方式

下面给出一个具体的NS2仿真示例,一遍可以更快更清楚地了解网络仿真的实际操作流程。例如,在文本编辑器中写入OTcl脚本。

脚本内容如下:

set ns [new Simulator]    #建立一个ns对象

#设定第一条数据流在nam中用蓝色表示,第二条数据流用红色表示,主要是为了便于观察被传送和丢弃的数据包是属于哪个数据流,其中参数1、2为数据流所对应的flowid(流量标识符)

$ns color 1 Blue

$ns color 2 Red

set nf [open out.nam w]   #打开跟踪文件out.nam,其中nf为文件句柄

$ns namtrace-all $nf 

proc finish {} {           #定义结束过程 

global ns nf 

$ns flush-trace

close $nf                 #关闭跟踪文件

    exec nam out.nam &    #调用nam

exit 0

 

set ns0 [$ns node]           #建立四个节点:n0、n1、n2、n3

set ns1 [$ns node]

set ns2 [$ns node]

set ns3 [$ns node] 

 

#建立节点间的链路Link、设置带宽1Mbit/s,时延10ms,队列DropTail,即先进先出(FIFO)

$ns duplex-link $ns0 $ns2 1Mb 10ms DropTail      

$ns duplex-link $ns1 $ns2 1Mb 10ms DropTail

$ns duplex-link $ns3 $ns2 1Mb 10ms DropTail 

 

#设定节点在拓扑图中的位置,使得整个图看起来布局更为合理

$ns duplex-link-op $ns0 $ns2 orient right-down   

$ns duplex-link-op $ns1 $ns2 orient right-up

$ns duplex-link-op $ns2 $ns3 orient right

 

#设定nam中queue的位置,便于检测节点n2和n3之间链路的队列

$ns duplex-link-op $ns2 $ns3 queuePos 0.5 

 

#为节点n0建立一个UDP代理udp0,用于产生流量,并设定flowid(流量标识符)为1

set udp0 [new Agent/UDP]          

$udp0 set class_ 1

$ns attach-agent $ns0 $udp0 

 

#设置udp0产生CBR流量,每隔0.005s发送大小为500B的数据包

set cbr0 [new Application/Traffic/CBR]           

$cbr0 set packetSize_ 500

$cbr0 set interval_ 0.005

$cbr0 attach-agent $udp0

 

 

 

 

 

#为节点n1建立一个UDP代理udp1,用于产生流量,并设定flowid(流量标识符)为2

set udp1 [new Agent/UDP]

$udp1 set class_ 2

$ns attach-agent $ns1 $udp1 

 

#设置udp1产生CBR(Constant BitRate,固定比特率)流量,每隔0.005s发送大小为500B的数据包

set cbr1 [new Application/Traffic/CBR]

$cbr1 set packetSize_ 500

$cbr1 set interval_ 0.005

$cbr1 attach-agent $udp1 

 

#为节点n3建立一个Null代理null0,用以接收流量

set null0 [new Agent/Null]                       

$ns attach-agent $ns3 $null0 

 

#分别连接流量产生代理udp0、udp1和流量接收代理null0

$ns connect $udp0 $null0

$ns connect $udp1 $null0 

 

#排程,设置cbr0在仿真0.5s后开始传输数据,4.5s后停止传输数据;设置cbr1在仿真1.0s后开始传送数据,4.0s后停止传送数据

$ns at 0.5 "$cbr0 start"                     

$ns at 1.0 "$cbr1 start"

$ns at 4.0 "$cbr1 stop"

$ns at 4.5 "$cbr0 stop"

 

#仿真5.0s后,调用结束过程

$ns at 5.0 "finish" 

 

#执行仿真                              

$ns run    

 

保存脚本文件为example1.tcl,运行命令:ns example1.tcl

 

 

 

 

 

 

 

 

 

运行结果如下图所示:

 

                                    

点击窗口上的“PLAY”按钮,将动态显示仿真过程:

 

仿真0.5s后,结点n0开始向结点n2传送数据包,该数据流以蓝色动态显示,此时可以拖动窗口右上方的“Step”滑尺以减缓nam的速度:

 

 

 

 

 

 

 

仿真1.0s后,节点n1开始向节点n2传送数据包,以红色动态显示:

 

 

 

 

 

 

 

 

 

 

 

 

 

经过一段时间后,可观察到链路队列上的数据包如何被丢弃,因为脚本采用的是FIFO队列机制,所以两种颜色的数据包并没有被“公平”地丢弃,所丢弃的都是蓝色的数据包,这可以通过修改链路配置的队列机制来提高公平性。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3)        NS2仿真示例—Xgraph方式

由上面的仿真示例可以看出,采用nam方式显示的是整个仿真的动态过程,如数据包的传输、链路的断开、丢包等;若想显示仿真过程中的内部状态,如传输速率、各种峰值等,可采用NS2提供的另外一种方式—Xgraph方式。

下面给出另一个采用Xgraph显示方式的NS2仿真示例。其网络拓扑结构如下图所示,链路Link都是带宽1Mbit/s、时延100ms、采用FIFO队列,udp连接从节点n0、n1、n2到节点n4,对应的OTcl脚本如后面所示。

 

在文本编辑器中写入OTcl脚本,脚本内容如下:

 

#建立一个ns对象

set ns [new Simulator]      

 

        #打开输出文件

set f0 [open out0.tr w]     

set f1 [open out1.tr w]

set f2 [open out2.tr w]

 

        #for循环,建立n0~n4共5个节点

for { set i 0 } { $i<5 } {incr i}{         

    setn$i [$ns node]  

}

 

        #建立链路Link

$ns duplex-link $n0 $n3 1Mb 100msDropTail   

$ns duplex-link $n1 $n3 1Mb 100msDropTail

$ns duplex-link $n2 $n3 1Mb 100msDropTail

$ns duplex-link $n3 $n4 1Mb 100msDropTail

 

 

 

 

 

 

        #定义结束过程

proc finish {} {                           

    globalf0 f1 f2

    close$f0

    close$f1

    close$f2

    

         #调用Xgraph显示仿真结果

    execxgraph out0.tr out1.tr out2.tr -geometry 800x400 &

    exit0

}

 

 

        #定义过程,为节点node和流量接收代理sink建立UDP连接,产生Expoo流量,并设置流量的size(packetSize,数据包大小)、burst(burst_time,突发事件)、idle(idle_time,空闲时间)和rate(burst peakrate,峰率)等

proc attach-expoo-traffic { node sinksize burst idle rate } {

set ns [Simulator instance]

 

        #为节点node建立一个UDP代理source,用于产生流量

set source [new Agent/UDP]

$ns attach-agent $node $source

 

        #产生Expoo流量

set traffic [newApplication/Traffic/Exponential]  

 

        #设置Expoo流量的packetSize(数据包大小)、burst_time(突发时间)、idle_time(空闲时间)和rate(burst peakrate,峰率)等

$traffic set packetSize_ $size

$traffic set burst_time_ $burst

$traffic set idle_time_ $idle

$traffic set rate_ $rate

$traffic attach-agent $source

 

        #连接流量产生代理source和流量接收代理sink

$ns connect $source $sink

return $traffic

}

 

 

 

 

 

 

 

        #定义记录过程,周期性地记录3个流量接收代理sink0、sink1、sink2所接受到的数据流带宽,并分别写入3个文件f0、f1、f2中

proc record {} {                      

    globalsink0 sink1 sink2 f0 f1 f2

    setns [Simulator instance]

 

          #定义过程再次被调用的时间,即调用周期

    settime 0.5   

 

          #获取代理已接收的字节数,即变量bytes的值                  

    setbw0 [$sink0 set bytes_]

    setbw1 [$sink1 set bytes_]       

    setbw2 [$sink2 set bytes_]

 

          #获取当前时间

    setnow [$ns now]

 

          #计算带宽(单位:Mbit/s),将结果写入文件                

    puts$f0 "$now [expr $bw0/$time*8/1000000]"      

    puts$f1 "$now [expr $bw1/$time*8/1000000]"

    puts$f2 "$now [expr $bw2/$time*8/1000000]"

 

          #重置接收代理中的变量bytes的值

    $sink0set bytes_ 0              

    $sink1set bytes_ 0

    $sink2set bytes_ 0

 

          #重新排程

    $nsat [expr $now+$time] "record" 

}

 

        #为节点n4建立3个流量接收代理sink0、sink1、sink2

set sink0 [new Agent/LossMonitor]    

set sink1 [new Agent/LossMonitor]

set sink2 [new Agent/LossMonitor]

$ns attach-agent $n4 $sink0

$ns attach-agent $n4 $sink1

$ns attach-agent $n4 $sink2

 

 

 

 

 

        #调用attach-expoo-traffic过程,分别建立节点n0、n1、n2与流量接收代理sink0、sink1、sink2的UDP连接,产生并设置Expoo流量

set source0 [attach-expoo-traffic $n0$sink0 200 2s 1s 100k] 

set source1 [attach-expoo-traffic $n1$sink1 200 2s 1s 200k]

set source2 [attach-expoo-traffic $n2$sink2 200 2s 1s 300k]

 

        #排程

$ns at 0.0 "record"              

$ns at 10.0 "$source0 start"

$ns at 10.0 "$source1 start"

$ns at 10.0 "$source2 start"

$ns at 50.0 "$source0 stop"

$ns at 50.0 "$source1 stop"

$ns at 50.0 "$source2 stop"

$ns at 60.0 "finish"

 

        #执行仿真

$ns run

 

         保存文件为example2.tcl,运行命令:nsexample2.tcl

         运行结果如下所示:

 

Xgraph显示仿真过程中的内部状态,从图中可以看出,三条数据流的峰值依次为0.1Mbit/s、0.2Mbit/s和0.3Mbit/s

 

 

 

 

4.        实验总结

 

在nam辅助分析工具中发现ftp1在零秒开始启动,ftp2在第三秒时刻开始启动,都在第十秒停止,这符合设计目标。在发送端收到新一轮的确认包时发送包的数量也加一,传输的过程中队列的长度超过一定值时开始丢包。这由设定的队列最小的门限值和队列最大门限值决定。当队列长度小于最小门限值时一定不会丢包,只有超过最小门限值时才会发生丢包,且超过的越多丢弃的概率越大。当队列长度超过最大门限值时队列一定丢包。丢包后的确认包不再让发送窗口增大,反而从零开始增加。传送过程中,丢包不再决定于队列的长度了,而是根据平均队列长度随机丢弃,因为采用的是RED丢包机制。