NS2仿真实验报告3
实验名称:公交车移动周期模型及性能分析
实验日期:2015年3月16日~2015年3月21日
实验报告日期:2015年3月22日
一、实验环境(网络平台,操作系统,网络拓扑图)
运行平台:虚拟机VMwareWorkstation11.0
操作系统:Linux/CentOS6.5仿真分析工具:NS2.35中的仿真软件ns,图形界面工具nam,编译工具awk,图表编辑器xgraph
网络拓扑图:
二、 实验目的
建立简单回路城市公交模型,假定给回路中的每个公交车都配置一个数据收发装置,进行网络通信。在NS仿真平台上建立相应的运动模型,以及配置路由机制,和分析网络性能的方法,综合分析该网络模型的可行性。本实验的主要在于分析网络的性能,网络的运动模型将以时间段表述出来。
三、 实验内容及步骤(包括主要配置流程,重要部分截图)
在实验1和2的基础上,通过动态静态网络传输的周期性模型,进一步学习无线自组织网络,其中包括一些常见的无线网络传输协议DSDV(Destination Sequenced Distance Vector)目标序列距离路由矢量算法、AODV(Adhocon DemandDistance Vector Routing)Adhoc网络的距离矢量路由算法、DSR(Dynamic Source Routing)等。比较在该模型下,使用不同路由协议时,各网络传输连通的状况。根据图表总结归纳各网络协议的优缺点以及性能分析。
3.1编写一个tcl脚本一般分为以下几个步骤
1) 创建模拟器对象
用来定义和控制模拟过程。在这个过程中,首先创建一个simulator 对象。
# 创建新模拟器
set ns [new Simulator]
2) 设置跟踪文件
# 跟踪文件和NAM文件创建
set tracefd [open trace2.trw]
$ns trace-all $tracefd
set namtrace [open sim12.nam w]
$ns namtrace-all-wireless$namtrace $val(x) $val(y)
# 吞吐量跟踪文件建立(用于最后分析)
set f0 [open out01.tr w]
# 丢包率跟踪文件建立(用于最后分析)
set f5 [open lost02.tr w]
# 传输延时跟踪文件建立(用于最后分析)
set f10 [open delay02.tr w]
3) 创建网络拓扑结构
set topo [new Topography]
# 场景范围设置
$topo load_flatgrid $val(x) $val(y)
#定义属性值(无线网络环境的固定模式)
set val(chan) Channel/WirelessChannel ;#信道类型
set val(prop) Propagation/TwoRayGround ;#无线传输类型
set val(netif) Phy/WirelessPhy ;#网络接口类型
set val(mac) Mac/802_11 ;# MAC类型
set val(ifq) Queue/DropTail/PriQueue ;#接口队列类型
set val(ll) LL ;#链路层类型
set val(ant) Antenna/OmniAntenna ;#天线模式
set val(ifqlen) 50 ;#包的最大缓存数
set val(nn) 18 ;#移动节点个数
set val(rp) AODV ;# 路由协议(实验3的关键因素,与AODV替换)
set val(x) 1000 ;# 定义场景中X轴最大值
set val(y) 400 ;# 定义场景中Y轴最大值
Mac/802_11 set RTSThreshold_ 3000
Mac/802_11 set basicRate_ 1Mb
Mac/802_11 set dataRate_ 2Mb
4) 配置节点属性
# 对本次实验中将出现的无线节点的属性进行详细设置
$ns node-config-adhocRouting $val(rp) \
-llType $val(ll) \
-macType $val(mac) \
-ifqType $val(ifq) \
-ifqLen $val(ifqlen) \
-antType $val(ant) \
-propType $val(prop) \
-phyType $val(netif) \
-channelType $val(chan) \
-topoInstance $topo \
-agentTrace ON \
-routerTrace ON \
-macTrace OFF \
-movementTrace ON
for {set i 0} {$i <$val(nn) } {incr i} {
set node_($i)[$ns node]
$node_($i)random-motion 0 ;# disable randommotion无法随机游动
}
5) 创建拓扑结构
# 初始化节点位置
$node_(0) set X_ 100.0
$node_(0) set Y_ 250.0
$node_(0) set Z_ 0.0
$node_(1) set X_ 800.0
$node_(1) set Y_ 200.0
$node_(1) set Z_ 0.0
$node_(2) set X_ 100.0
$node_(2) set Y_ 200.0
$node_(2) set Z_ 0.0
$node_(3) set X_ 100.0
$node_(3) set Y_ 200.0
$node_(3) set Z_ 0.0
$node_(4) set X_ 100.0
$node_(4) set Y_ 200.0
$node_(4) set Z_ 0.0
$node_(5) set X_ 100.0
$node_(5) set Y_ 200.0
$node_(5) set Z_ 0.0
$node_(6) set X_ 100.0
$node_(6) set Y_ 200.0
$node_(6) set Z_ 0.0
$node_(7) set X_ 100.0
$node_(7) set Y_ 200.0
$node_(7) set Z_ 0.0
$node_(8) set X_ 100.0
$node_(8) set Y_ 200.0
$node_(8) set Z_ 0.0
$node_(9) set X_ 100.0
$node_(9) set Y_ 200.0
$node_(9) set Z_ 0.0
$node_(10) set X_ 800.0
$node_(10) set Y_ 250.0
$node_(10) set Z_ 0.0
$node_(11) set X_ 800.0
$node_(11) set Y_ 250.0
$node_(11) set Z_ 0.0
$node_(12) set X_ 800.0
$node_(12) set Y_ 250.0
$node_(12) set Z_ 0.0
$node_(13) set X_ 800.0
$node_(13) set Y_ 250.0
$node_(13) set Z_ 0.0
$node_(14) set X_ 800.0
$node_(14) set Y_ 250.0
$node_(14) set Z_ 0.0
$node_(15) set X_ 800.0
$node_(15) set Y_ 250.0
$node_(15) set Z_ 0.0
$node_(16) set X_ 800.0
$node_(16) set Y_ 250.0
$node_(16) set Z_ 0.0
$node_(17) set X_ 800.0
$node_(17) set Y_ 250.0
$node_(17) set Z_ 0.0
# 定义节点大小用于在nam中查看
for {set i 0} {$i < $val(nn)} {incr i} {
$ns initial_node_pos$node_($i) 20
}
#节点的运动路径
$ns at 10.0 "$node_(0) setdest 50.0 350.0 30.0"
$ns at 20.0 "$node_(0) setdest 350.0 350.0 30.0"
$ns at 30.0 "$node_(0) setdest 350.0 50.0 30.0"
$ns at 40.0 "$node_(0) setdest 50.0 50.0 30.0"
$ns at 10.0 "$node_(1) setdest 350.0 50.0 60.0"
$ns at 15.0 "$node_(1) setdest 50.0 50.0 60.0"
$ns at 20.0 "$node_(1) setdest 50.0 350.0 60.0"
$ns at 25.0 "$node_(1) setdest 350.0 350.0 60.0"
$ns at 30.0 "$node_(1) setdest 350.0 50.0 60.0"
$ns at 35.0 "$node_(1) setdest 50.0 50.0 60.0"
$ns at 40.0 "$node_(1) setdest 50.0 350.0 60.0"
$ns at 45.0 "$node_(1) setdest 350.0 350.0 60.0"
for {set i 0} {$i < $val(nn)} {incr i} {
$ns initial_node_pos$node_($i) 20
}
$ns at 0.0 "$app1 start"
$ns at 0.0 "$node_(2) setdest 800.0 200.0 50.0"
$ns at 14.0 "$node_(2) setdest 800.0 250.0 50.0"
$ns at 15.0 "$node_(2) setdest 100.0 250.0 50.0"
$ns at 29.0 "$node_(2) setdest 100.0 200.0 50.0"
$ns at 2.0 "$node_(3) setdest 800.0 200.0 50.0"
$ns at 16.0 "$node_(3) setdest 800.0 250.0 50.0"
$ns at 17.0 "$node_(3) setdest 100.0 250.0 50.0"
$ns at 31.0 "$node_(3) setdest 100.0 200.0 50.0"
$ns at 4.0 "$node_(4) setdest 800.0 200.0 50.0"
$ns at 18.0 "$node_(4) setdest 800.0 250.0 50.0"
$ns at 19.0 "$node_(4) setdest 100.0 250.0 50.0"
$ns at 33.0 "$node_(4) setdest 100.0 200.0 50.0"
$ns at 6.0 "$node_(5) setdest 800.0 200.0 50.0"
$ns at 20.0 "$node_(5) setdest 800.0 250.0 50.0"
$ns at 21.0 "$node_(5) setdest 100.0 250.0 50.0"
$ns at 35.0 "$node_(5) setdest 100.0 200.0 50.0"
$ns at 8.0 "$node_(6) setdest 800.0 200.0 50.0"
$ns at 22.0 "$node_(6) setdest 800.0 250.0 50.0"
$ns at 23.0 "$node_(6) setdest 100.0 250.0 50.0"
$ns at 37.0 "$node_(6) setdest 100.0 200.0 50.0"
$ns at 10.0 "$node_(7) setdest 800.0 200.0 50.0"
$ns at 24.0 "$node_(7) setdest 800.0 250.0 50.0"
$ns at 25.0 "$node_(7) setdest 100.0 250.0 50.0"
$ns at 39.0 "$node_(7) setdest 100.0 200.0 50.0"
$ns at 12.0 "$node_(8) setdest 800.0 200.0 50.0"
$ns at 26.0 "$node_(8) setdest 800.0 250.0 50.0"
$ns at 27.0 "$node_(8) setdest 100.0 250.0 50.0"
$ns at 41.0 "$node_(8) setdest 100.0 200.0 50.0"
$ns at 14.0 "$node_(9) setdest 800.0 200.0 50.0"
$ns at 28.0 "$node_(9) setdest 800.0 250.0 50.0"
$ns at 29.0 "$node_(9) setdest 100.0 250.0 50.0"
$ns at 43.0 "$node_(9) setdest 100.0 200.0 50.0"
$ns at 0.0 "$node_(10) setdest 100.0 250.0 50.0"
$ns at 14.0 "$node_(10) setdest 100.0 200.0 50.0"
$ns at 15.0 "$node_(10) setdest 800.0 200.0 50.0"
$ns at 29.0 "$node_(10) setdest 800.0 250.0 50.0"
$ns at 2.0 "$node_(11) setdest 100.0 250.0 50.0"
$ns at 16.0 "$node_(11) setdest 100.0 200.0 50.0"
$ns at 17.0 "$node_(11) setdest 800.0 200.0 50.0"
$ns at 31.0 "$node_(11) setdest 800.0 250.0 50.0"
$ns at 4.0 "$node_(12) setdest 100.0 250.0 50.0"
$ns at 18.0 "$node_(12) setdest 100.0 200.0 50.0"
$ns at 19.0 "$node_(12) setdest 800.0 200.0 50.0"
$ns at 33.0 "$node_(12) setdest 800.0 250.0 50.0"
$ns at 6.0 "$node_(13) setdest 100.0 250.0 50.0"
$ns at 20.0 "$node_(13) setdest 100.0 200.0 50.0"
$ns at 21.0 "$node_(13) setdest 800.0 200.0 50.0"
$ns at 35.0 "$node_(13) setdest 800.0 250.0 50.0"
$ns at 8.0 "$node_(14) setdest 100.0 250.0 50.0"
$ns at 22.0 "$node_(14) setdest 100.0 200.0 50.0"
$ns at 23.0 "$node_(14) setdest 800.0 200.0 50.0"
$ns at 37.0 "$node_(14) setdest 800.0 250.0 50.0"
$ns at 10.0 "$node_(15) setdest 100.0 250.0 50.0"
$ns at 24.0 "$node_(15) setdest 100.0 200.0 50.0"
$ns at 25.0 "$node_(15) setdest 800.0 200.0 50.0"
$ns at 39.0 "$node_(15) setdest 800.0 250.0 50.0"
$ns at 12.0 "$node_(16) setdest 100.0 250.0 50.0"
$ns at 26.0 "$node_(16) setdest 100.0 200.0 50.0"
$ns at 27.0 "$node_(16) setdest 800.0 200.0 50.0"
$ns at 41.0 "$node_(16) setdest 800.0 250.0 50.0"
$ns at 14.0 "$node_(17) setdest 100.0 250.0 50.0"
$ns at 28.0 "$node_(17) setdest 100.0 200.0 50.0"
$ns at 29.0 "$node_(17) setdest 800.0 200.0 50.0"
$ns at 43.0 "$node_(17) setdest 800.0 250.0 50.0"
6) 设置代理和应用层协议并进行绑定
set agent1 [new Agent/UDP] ;# 创建UDP代理
$agent1 set prio_ 0
# 创建Loss Monitor Sink检验丢失分组
set sink [new Agent/LossMonitor]
$ns attach-agent $node_(0)$agent1 ; #发射代理与节点连接(以下几个意义相同)
$ns attach-agent $node_(1)$sink ; # 接收代理与节点连接(以下几个意义相同)
$ns connect $agent1$sink
# 两节点相连(以下几个意义相同)
set app1 [new Application/Traffic/CBR]; # 创建流量发射器(以下几个意义相同)
$app1 set packetSize_ 512 ;# 定义包大小(以下几个意义相同)
$app1 set rate_ 600Kb ;# 定义发射频率(以下几个意义相同)
$app1 attach-agent $agent1; # 连接流量发射器和代理(以下几个意义相同)
set agent2 [new Agent/UDP]
$agent2 set prio_ 1
set sink2 [new Agent/LossMonitor]
$ns attach-agent $node_(3)$agent2
$ns attach-agent $node_(4)$sink2
$ns connect $agent2$sink2
set agent34 [new Agent/UDP]
$agent34 set prio_ 1
set sink34 [new Agent/LossMonitor]
$ns attach-agent $node_(5)$agent34
$ns attach-agent $node_(6)$sink34
$ns connect $agent34$sink34
set agent3 [new Agent/UDP]
$agent3 set fid_ 3
$agent3 set prio_ 2
set sink3 [new Agent/LossMonitor]
$ns attach-agent $node_(7)$agent3
$ns attach-agent $node_(8)$sink3
$ns connect $agent3$sink3
set agent4 [new Agent/UDP]
$agent4 set prio_ 3
set agent45 [new Agent/UDP]
$agent45 set prio_ 1
set sink45 [new Agent/LossMonitor]
$ns attach-agent $node_(9)$agent45
$ns attach-agent $node_(10)$sink45
$ns connect $agent45$sink45
set sink4 [new Agent/LossMonitor]
$ns attach-agent $node_(11) $agent4
$ns attach-agent $node_(12)$sink4
$ns connect $agent4$sink4
set agent78 [new Agent/UDP]
$agent78 set prio_ 1
set sink78 [new Agent/LossMonitor]
$ns attach-agent $node_(13)$agent78
$ns attach-agent $node_(14)$sink78
$ns connect $agent78$sink78
set agent5 [new Agent/UDP]
$agent5 set prio_ 4
set sink5 [new Agent/LossMonitor]
$ns attach-agent $node_(15)$agent5
$ns attach-agent $node_(16)$sink5
$ns connect $agent5 $sink5
7) 使用模拟器对象的at过程设置节点事件和时间的对应关系
# 定时发包开始及结束
$ns at 0.0 "record"
$ns at 1.0 "$app1start"
$ns at 50.0 "$app1 stop"
$ns at 50.0 "stop"
# 在50秒的时候重置节点
for {set i 0} {$i < $val(nn) } {incr i} {
$ns at 50.0 "$node_($i)reset";
}
8) 记录实验数据
# 创建record函数来记录数据
proc record {}{
global sink sink2 sink3 sink4 sink5 f0 f5holdtime holdseq holdtime1 holdseq1 holdtime2 holdseq2 holdtime3 holdtime4holdseq3 holdseq4 f10 holdrate1 holdrate2 holdrate3 holdrate4 holdrate5
set ns [Simulator instance]
set time 0.9 ;# 设置采样时间
set bw0 [$sink set bytes_]
set bw5 [$sink set nlost_]
set bw10 [$sink set lastPktTime_]
set bw11 [$sink set npkts_]
set now [$ns now]
# 计算吞吐量并写入out02.tr、out12.tr、out22.tr、out32.tr文件
puts $f0"$now [expr (($bw0+$holdrate1)*8)/(2*$time*1000000)]"
# 计算丢包率并写入lost02.tr、lost12.tr、lost22.tr、lost32.tr
puts $f5"$now [expr $bw5/$time]"
# 计算延时并写入delay02.tr、delay12.tr、delay22.tr、delay32.tr
if { $bw11 >$holdseq } {
puts $f10 "$now [expr ($bw10 -$holdtime)/($bw11 - $holdseq)]"
} else {
puts $f10 "$now [expr ($bw11 -$holdseq)]"
}
9) 使用模拟器对象的run过程开始模拟
proc stop {} {
global ns tracefd f0 f5 f10
#关闭trace文件,停止记录
close $f0
close $f5
close $f10
# 用 xgraph 把吞吐量,丢包率,和延时显示在图像上
exec xgraph out02.tr out12.trout22.tr -geometry 800x400 &
exec xgraph lost02.tr lost12.trlost22.tr lost32.tr -geometry 800x400 &
exec xgraph delay02.tr delay12.trdelay22.tr delay32.tr -geometry 800x400 &
exec nam sim12.nam
# 重置Trace文件
$ns flush-trace
close $tracefd
exit 0
}
puts"Starting Simulation..."
$ns run
10) 结果分析
模拟结束后,将得到保存模拟过程的traced文件,接下来的主要工作就是对于这个结果文件根据需求进行数据分析,同时可以用xgraph等画图工具直观的显示数据分析结果。
四、 实验结果(包括最终实验结果,重要部分截图)
4.1移动模型节点切换分析
仿真开始时间为0.0s,此时执行代码$ns at0.0 "$app1 start",节点0和1之间通过中间的16个基站,寻找最佳的传输路径。节点0作为发射器,节点1作为接收器。公交车以一定的班车时间在环形公路上周期性行驶。
在第5.4s时,此时节点0和1通过节点2传输数据。由节点0开始发出广播依次传递给附近的移动节点,由移动节点依次向前洪泛式传播消息。最终将携带消息传递到目标节点1中去。
第5.5s时,由节点1返回一个确认消息,节点0开始向节点1发送数据,直到路由信息发生变化为止。此时的链路为:0->4->2->10->11->1。
第5.8s时,由于节点的运动,出现远离最初连接的基站节点,距离远到数据无法继续传输时,节点0发送的信息几乎全部丢失,于是所有节点重新开始匹配新的路由信息。
第9.0s时,节点经过再次的匹配,连接到新的基站节点10和节点2上,数据传输开通。此时的链路为:0->10->2>1。
第9.6s时节点10远离节点2,出现严重的数据丢失后,切换到节点7节点通路为:0->5->11->12->13->1。 AODV协议的按需基于距离矢量的特性,使得节点之间始终保持在最佳连通状况。
第11.2s时,由于公交车的移动,路由发生变化AODV协议为节点选择最佳的通信链路,此时的链路为:1->6>->4->2->1。
第12.8s时,链路发生变化为:0->10->6->14->2->1。
第14.2s时,链路发生变化为:0->7->5->4->1。
第15.2s时,链路发生变化为:0->9->7->15->1。
第19.1s时,链路发生变化为:0->10->8->2->1。
第20.3s时,链路发生变化为:0->14->9->3->1。
第20.4s时,链路发生变化为:0->14->9->7->1。
第20.9s时,链路发生变化为:0->14->16->3->1。
第26.3s时,信息的传递出现小范围的环路,链路为:0->14->16->3,并未传递到目标节点1中去。此时节点16和14正向接收节点1移动,节点3向节点0移动,在26.3s-28.4s之间正常通信,但在28.4s时节点3距离节点1的距离超过了可通信的范围,出现连路中断,而路由协议则认为,依据距离矢量方法依然可以同行,所以出现了严重的数据丢失。
第28.4s时,链路发生变化为:0->15->13->11->1。
第29.6s时,链路发生变化为:0->2->4->6->12->1。
第32.7s时,链路发生变化为:0->2->5->6->8->13->1。
第35.4s时,链路发生变化为:0->14->9->7->1。此后移动节点2-9和移动节点10-17沿着公交路线环绕一周,陆续回到原来的起点处。不可避免的出现链路的中断。
4.2吞吐量、丢包率以及延时的分析
1.计算 TCP吞吐量的公式
TCP窗口大小(bits) / 延迟(秒) = 每秒吞吐量(bits)
2.计算最优 TCP窗口大小的公式
带宽(bits每秒) * 往返延迟(秒) = TCP窗口大小(bits) / 8 = TCP窗口大小(字节)
3.给定吞吐量计算最大延迟的公式
TCP窗口大小(bits) / 吞吐量(bits每秒) = 最大往返延迟时间
如下图所示,仿真开始时间是5.0s。数据传输处于请求转发时期,在5.8s时数据开始丢失,一直持续到仿真时间第9.0s,数据链路才处于接通状态。第20.0s时发生小范围的回路现象,导致数据严重丢失,持续到26.0s时恢复通信。
如下图所示,节点0和节点1之间数据传输,节点1的丢包在15s左右出现严重的缺失,这是因为15s时,节点0和1由于通信距离不在两者在范围之内,重新进行切换到新的基站节点中去。
节点0和1在仿真开始时处于未接通状态,所以首先要经过各节点进行协商,设置出转接通信的节点,此时由上述的实验步骤可以看出,在第5.4s时开始建立通信,节点0发出建立连接的消息,到节点1中去,数据通信的时延较长,随后数据连通后,数据通信延时减少。
五、试验中的问题及心得
5.1一些出现最多的问题
问题1
num_nodes is set18
warning: Pleaseuse -channel as shown in tcl/ex/wireless-mitf.tcl
INITIALIZE THELIST xListHead
StartingSimulation...
channel.cc:sendUp- Calc highestAntennaZ_ and distCST_
highestAntennaZ_= 1.5, distCST_ = 550.0
SORTING LISTS...DONE!
Segmentationfault (core dumped)
应考虑加上如下的代码:
set val(rp)DSR ;# 路由协议(实验2的关键因素,与AODV替换)
NS2文件中不存在协议DSR,这是因为有些协议是需要自己配置的。
问题2
ns: puts"NS EXITING..." _o3 halt:wrong # args: should be "puts ?-nonewline? ?channelId? string"
while executing
"puts"NS EXITING..." _o3 halt"
考虑结束控制命令$ns at 60.0 "puts \"NSEXITING...\" $ns halt",中是否缺少分号”;”,即$ns at 60.0 "puts \"NSEXITING...\" ; $ns halt"。
还要考虑数据传输开始和结束的控制命令,也有可能引起这样的错误。
六、实验思考
本次实验主要是通过学习移动节点在实际中是如何,通过不同的协议,比如在本实验中采用的是AODV路由协议,这时,通信节点之间自动的按照协议所规定的方法在仿真场景中进行连接。在上述实验中不宜使用DSDV协议,因为DSDV路由协议所有的节点都必须被告知路由信息,节点将长时间处于寻找路由的过程中,而不是进行通信。因此DSDV协议适用于节点稀疏时,易于实现的模型当中。
而AODV路由协议不同于表驱动路由协议,是一种特殊的按需距离矢量的反应式路由协议,每个节点中记录自己可达的节点,一旦出现某个节点不可达,则自动删除该记录,修复链路的连通性。大多数时间保持在一种可通信的状态。这种协议适用于节点密度比较大的情况,节和节点之间几乎是可实时通信的情况。