NS2仿真实验分析报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
NS2仿真实验分析报告
一引言
1 NS2简介
NS2是一款开放源代码的网络模拟软件,最初由UC Berkeley开发。
它是一种向象的网络模拟器,它本质上是一个离散事件模拟器,其本身有一个模拟时钟,所有的模拟都由离散事件驱动。
其采用了分裂对象模型的开发机制,采用C++和OTcl两种语言进行开发。
它们之间采用Tclcl 进行自动连接和映射。
考虑效率和操作便利等因素,NS2将数据通道和控制通道的实现相分离。
为了减少分组和事件的处理时间,事件调度器和数据通道上的基本网络组件对象都使用C++编写,这些对象通过Tclcl映射对OTcl解释器可见。
目前NS2可以用于模拟各种不同的通信网络,它功能强大,模块丰富,已经实现的主要模块有:网络传输协议,如TCP和UDP;业务源流量产生器,如FTP、Telnet、CBR、We b和VBR;路由队列管理机制,如DropTail、RED和CBQ;路由算法;以及无线网络WLAN、移动IP和卫星通信网络等模块,也为进行局域网的模拟实现了多播协议以及一些MAC子层协议。
2 基本概念
(1)RED:随机早期探测(Random Early Detect,RED)。
RED属于主动队列管(Active Queue Management, AQW),是目前常见的TCP上防止拥塞的手段。
它通过以一定概率丢失或标记报文来通知端系统网络的拥塞情况。
RED使用平均队列长度度量网络的拥塞程度,然后以线性方式将拥塞信息反馈给端系统。
RED使用最小阈值,最大阈值和最大概率等几个参数。
RED的基本思想是通过监控路由器输出端口队列的平均长度来探测拥塞,一旦发现拥塞逼近,就随机地选择连接来通知拥塞,使它们在队列溢出导致丢包之前减少拥塞窗口,降低发送数据速度,缓解网络拥塞。
RED配置在路由器监视网络流量以便避免拥塞,当拥塞即将发生时,它随机丢弃进来的分组,而不是等到队列缓冲区满是才开始丢弃所有进来的分组,这样可以最少化全局同步的发生。
当拥塞发生时,RED丢弃每个连接分组的概率与该连接占用的带宽成比例,它监视每个输出队列的平均队列长度,随机选择分组丢弃。
(2)丢包率:是一个比率,表示在单位时间内未收到的数据分组数与发送的数据分组数的比率,由于信号衰减、网络质量等诸多因素的影响,可能产生数据分组的丢失。
(3)端到端时延:是由各种因素引起的,包括打包和解包时延,以及网络传送时延,本文中主要讨论的是网络传输时延。
(4)吞吐量:单位时间内,某个节点发送和接受的数据量,单位一般为b/s。
二NS2网络仿真机制与过程
使用NS2进行网络仿真的基本操作流程如图1所示,用户首先要进行问题定义,考虑自己要仿真什么东西、拓扑结构应该怎样、是否需要对源代码进行修改或添加等。
如果需要添加或修改代码,如图1中右边方框中所示,有一个对NS2源码进行修改、重新编译和调试的过程;如果不需要修改代码,即采用NS2已有构件即可完成仿真工作,那么用户的主要任务就是编写Tcl/OTcl仿真代码,生成一个.tcl脚本文件,并用NS2执行该脚本进行仿真,仿真程序结束后会生成相应的Trace文件,即仿真结果文件,用户使用不同的工具对该脚本中的内容进行分析得到我们想要的结果和图表,如果结果是我们的预期,那么整个仿真过程即可顺利结束,否则应该分析问题所在,并重新考虑问题定义、源码修改、Tcl脚本修改的必要性。
整个仿真过程主要有三部分的工作量:修改源代码、编写Tcl仿真脚本和分析结果。
(1)源码修改。
这一步只有在仿真需要修改源代码时才进行考虑,修改源代码是一项比较具有挑战性的工作,这需要用户有一定的编程和调试水平。
特别需要注意的是,由于NS2是采用C++和OTcl两种语言编写的,因此在修改源代码时,需要记着修改相应的OTcl代码。
(2)Tcl/OTcl仿真代码编写。
这是NS2仿真中最重要和必不可少的一环,大部分NS2的仿真工作实际就是编写Tcl代码来描述网络结果、网络构件属性和控制调度网络模拟事件的启停的过程。
因此,这需要用户对NS2中的网络构件非常熟悉。
(3)仿真结果分析。
结果分析是真正体现仿真工作成效的重要一环,仿真结果分析要求用户熟悉NS2的Trace文件的结构,并且能够使用一些小工具对该结果文件进行分析以及根据分析结果数据绘制一些汇总图标等。
图1 基本操作流程图
三实验过程与结果分析
1 仿真实验的模拟情节配置说明
本仿真情节包含4个node,各节点之间都是以全双工的链路相连。
n0和n2之间链路的带宽为2Mbps,延迟为10ms,为DropTail队列方式;n1和n2之间链路带宽为2Mbps,延迟为10ms,也为DropTail队列方式;网络拓扑中的带宽瓶颈是在节点n2到节点n3之间,带宽为1.7Mbps,延迟为20ms,同为DropTail方式,且最大队列长度为10个数据包长度。
在n0到n3之间建立了基于TCP协议凡人FTP应用,TCP包的长度采用默认的1Kbytes。
另外,在n1到n3之间建立一条基于UDP协议的CBR应用。
CBR的传递速度为1Mbps,每个包大小为1Kbytes。
CBR业务在0.1秒开始传送,在4.5秒结束传送。
FTP业务在1.0秒开始传送,4.0秒结束传送。
写出仿真脚本并运行,会自动弹出Nam窗口。
通过Nam可以依次看到如图2、图3、图4所示的动态过程。
图中红色代表基于UDP的CBR业务流,蓝色代表基于TCP的FTP业务流。
模拟一开始只有CBR业务流出现,网络依次传递这些数据包,因为各段链路带宽均大于CBR业务速率(1Mbps),网络没有出现排队与丢包现象,如图2所示。
图2 CBR业务启动
图3 网络出现排队现象
图4 网络出现丢包现象
随后FTP业务启动,随着慢启动的开始,FTP的数据速率越来越高,给网络带来很大压力,瓶颈链路n2与n3之间出现排队现象。
并且可看到使用TCP传输数据时,接收方会对收到的数据进行确认,而UDP协议传输时,不发回确认。
整个过程如图3所示。
最终,随着FTP速率的提高,当n2与n3之间的队列占满后,会出现丢包现象,这时TCP协议将会进入拥塞控制,进入慢启动过程,如图4所示。
2 Trace文件格式说明
(1)event:“+”:表示分组进入链路队列事件;“—”:表示分组离开链路队列事件;“r”:表示目的节点接受分组事件;“d”:表示队列丢弃分组事件
(2)time:事件发生的时间
(3)from node:分组发送接点的id
(4)to node:分组传送的目的节点的id
(5)pkt type:分组类型
(6)pkt size:分组大小
(7)flags:标志项
(8)fid:流标识符
(9)src addr:源地址,格式为node.port,其中node代表分组发送节点的id,port表示发送分组的端口号。
(10)dst addr:目的地址,格式为node.port,其中node代表分组发送节点的id,port表示发送分组的端口号
(11)seq num:分组的序列号
(12)pkt id:分组的唯一标识符。
3 数据处理
在NS2中,模拟产生的Trace文件往往非常大,一般情况下,需要借助Gawk对其进行处理,提取相应的数据信息。
(1)处理n1到n3端点间CBR丢包情况,测量程序写在lostRate.awk文件中
执行方法:$awk -f lostRate.awk out.tr
执行结果:
#number of packet sent:550,lost:8
#lost rate of packets:0.014545
0.100000 0.000000
0.108000 0.000000
0.116000 0.000000
运行结果中显示CBR流量总共发包550,丢失8,丢包率为:0.014545。
同理,我们可以编写延时与吞吐量的awk文件。
我们通过执行如下语句将丢包率、延时、吞吐量保存在cbr_lostRate、cbr_delay、cbr_throughput文件中。
执行方法:
$ awk -f lostRate.awk out.tr>cbr_lostRate
$ awk -f delay.awk out.tr>cbr_delay
$ awk -f throughput.awk out.tr>cbr_throughput
在Xwin窗口中输入xgraph cbr_lostRate,就可以把前面所存下来的cbr_lostRate文件使用图形直观的表示出来,如图5所示。
图5 丢包率随时间变化的关系图
(2)我们可以得到CBR流量的时延随时间的变化如图6所示:
图6 端到端时延随时间变化的关系图
(3)节点n2的平均吞吐量随时间的变化如图7所示:
图7 节点n2的吞吐量随时间变化的关系图
4 结果分析
从RED的图示中,可以看出队列的大小波动变化不是很大,在处理突发的包时有一定的优势。
从丢包率、时延和吞吐量的变化图中,可以看出当丢包率增加时,端到端之间的时延也在增加,而吞吐量则下降,丢包率、时延和吞吐量在表示网络性能的好坏时有一定的关系。
四部分相关代码
1.网络拓扑仿真脚本ns-simple.tcl
#Create a simulator object
set ns [new Simulator]
#Define different colors for data flows (for NAM)
$ns color 1 Blue
$ns color 2 Red
#Open the NAM trace file
set nf [open out.nam w]
$ns namtrace-all $nf
set tf [open out.tr w]
$ns trace-all $tf
#Define a 'finish' procedure
proc finish {} {
global ns nf tf
$ns flush-trace
#Close the NAM trace file
close $nf
close $tf
#Execute NAM on the trace file
exec nam out.nam &
exit 0
}
#Create four nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
#Create links between the nodes
$ns duplex-link $n0 $n2 2Mb 10ms DropTail $ns duplex-link $n1 $n2 2Mb 10ms DropTail $ns duplex-link $n2 $n3 1.7Mb 20ms DropTail
#Set Queue Size of link (n2-n3) to 10
$ns queue-limit $n2 $n3 10
#Give node position (for NAM)
$ns duplex-link-op $n0 $n2 orient right-down $ns duplex-link-op $n1 $n2 orient right-up $ns duplex-link-op $n2 $n3 orient right
#Monitor the queue for link (n2-n3). (for NAM) $ns duplex-link-op $n2 $n3 queuePos 0.5
#Setup a TCP connection
set tcp [new Agent/TCP]
$tcp set class_ 2
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n3 $sink
$ns connect $tcp $sink
$tcp set fid_ 1
#Setup a FTP over TCP connection
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP
#Setup a UDP connection
set udp [new Agent/UDP]
$ns attach-agent $n1 $udp
set null [new Agent/Null]
$ns attach-agent $n3 $null
$ns connect $udp $null
$udp set fid_ 2
#Setup a CBR over UDP connection
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 1mb
$cbr set random_ false
#Schedule events for the CBR and FTP agents
$ns at 0.1 "$cbr start"
$ns at 1.0 "$ftp start"
$ns at 4.0 "$ftp stop"
$ns at 4.5 "$cbr stop"
#Detach tcp and sink agents (not really necessary)
$ns at 4.5 "$ns detach-agent $n0 $tcp ; $ns detach-agent $n3 $sink"
#Call the finish procedure after 5 seconds of simulation time
$ns at 5.0 "finish"
#Print CBR packet size and interval
puts "CBR packet size = [$cbr set packet_size_]"
puts "CBR interval = [$cbr set interval_]"
#Run the simulation
$ns run
2处理时延的awk代码delay.awk
#delay analyse
BEGIN{
highestPktId=0;
}
{
event = $1;
time = $2;
fromNode = $3;
toNode = $4;
pktType = $5;
pktSize = $6;
flags = $7;
fid = $8;
srcAddr = $9;
dstAddr = $10;
seqNum = $11;
pktId = $12;
if(pktId>highestPktId)
highestPktId=pktId;
if(beginTime[pktId]==0)
beginTime[pktId]=time;
if(fid==2 && event!="d"){
if(event=="r")
endTime[pktId]=time;
}else{
endTime[pktId]=-1;
}
END{
for(pktId=0;pktId<=highestPktId;pktId++)
{
begin=beginTime[pktId];
end=endTime[pktId];
pktDuration=end-begin;
if(begin<end)
printf("%f\t%f\n",begin,pktDuration);
}
}
11。