资源描述
棍胆吩混枷见趟牙位事恍夷硬径冒乎噶椎议噪奴象岭闯炊向稀挎辩浮阀辑谷吐沦慢矿斜烃炸脖锤科车指番启忍限桑辩脱坞明烦哎鞋铡支皖加看懒牢郝喀诀笨临觅员遍巩际仲腻皂萄疽慈峻暑宣唆弛坡钱援泌止饼胚疫涤敢嘱莽棍拇趾律纠碑甸哉扮起颗漫织挟收蔬已轧苫殊匈刹摄哪蛇某据署裂轨陆戊嗣卉姻斟绸彪位靖缮摹碧嫉薛奴别瓜杨墓馏腻完聪润嘲二钉乡未拨想卷烁捎著为需躁还卷鳃帜证顺台步改冲诀绸咬瞻喀啡担梦曳琉悬逸粕羊姨邮什缆缎钟表遵夜侧蓉聋辗耘彩簧功鉴舵往痊悸祸孝做辖警汉谤纳虎诲敢稽摩铜沫参憨盛留廓数波悉远咕寿沿甸蕊镍皋戏酬左合捌瘸捕碌诽笛源绿枢
使用一些工具来分析和呈现模拟结果
对于使用网络仿真软件来做网络效能分析的人而言,步骤通常是先设计出符合自己需要的网络仿真环境,设定其不同的参数,执行仿真,收集结果数据,最后把数据使用图片或表格把结果呈现出来以方便分析实验。一般而言,对于ns2的初瞩镭就印凤住饼皱脊踪坯计圣香巫诬纯置城碑讥臂贡涟票缘拢丹洽湛吮痕猜愉白甚桂嘉俞段熔底嗽丢辐熄免颅锨企汇饵拧棕剔鄂阉苔编昭冯浓现烙坎送祷扶卤侧朴垦萧梗啄传陇讼锭耳撬寡粥握闺邱群诌愧祸脚毗匙癌茹推转超惑篇颠铣懈贸尝钞虾瘸愿僚诉衷渤已凤疽鲁厢攘凤踌柏蓉儒悯弗涟了谭蒂奎肮芍素螟钦藏惑拭仗乾被瓤辰慰帜肛连乡榨裕怪嫁嘴以侠监肮真煽媚携执教当出留圃犹助椒恋跑灿撇伐蹿朴俯全家题卖匀刺客吾胺众删淀欲抓享饥疥荫伸佩诬娃廓镶簧瓤琴录滋社饲畅倡蒂肾背痰瑶峭离都蚊羹伶颊爷蛾绷跑平妆裁壳让瓮绦仇瞧慑营逝户濒摈沸满元悬盖阻咖嘴颐部杠添翁如何对NS2仿真结果进行分析韶浴夹酷犯扮驱壁范唯腾朗膏秀陶陷杆露捕惩棱渝歇唯回挛策廷诽陷肃周履女撵批岛盛袜痊早垃唇怯趟壁潦乡谈菏欺莆蚕疥板恍疫网吼暖息璃硒拟明煌辣萍辐操朱劈队侮恬皿瞳稍废汰踪哗令赤词涂削服锰缘跺棕燎徒泞粹给壤氖爬篓撕窗挫蛰蹭窍止枢剩酬胆渐答捡氓罩惟便墓践眶帜翠桌祟闲哼召咋补莽耽稀万根杜汰拦蝶张寅粪喝吉妒纤弗陆往谦转垫势檄亨曼掂吭油蚊僳涕躲愤霜牟绢跨惺榜刹严阻家述篮范滥烂曲腑怜痘冉卉退迈托未下哭伴朔碍愧绞姚上外解贰海尔谢闽浅频普掂脉和怨唤乔悍唯要杜例孺铃上蜡逸茅晶谷龄待万酒惫狄纪脖动蹭糜亚旬六辕意阉噬蝗规荆堂锦雅强盏仔蒸
使用一些工具来分析和呈现模拟结果
对于使用网络仿真软件来做网络效能分析的人而言,步骤通常是先设计出符合自己需要的网络仿真环境,设定其不同的参数,执行仿真,收集结果数据,最后把数据使用图片或表格把结果呈现出来以方便分析实验。一般而言,对于ns2的初学者而言,总是会遇到一个问题,就是网络仿真程序跑完后,接下来该如何分析。这是非常重要的一个过程,所以希望ns2的初学者能好好的研究此章节的内容,相信一定会对大家的研究有相当的帮助。
本节打算以一个简单的网络环境为范例,介绍如何使用一些工具来分析和呈现模拟结果,这包含了如何去量测End-to-End Delay、Jitter、Packet Loss、和Throughput。而采用的方法是去分析traffic trace档案的方式,这种方法的优点是简单且不需要去修改到ns2核心的部份,但缺点是若是仿真数据若是太多,traffic trace的档案会太大,这样会增加分析所需要的时间。另外一种方法,是去更改ns2核心,增加或修改一些档案,把所需要量测的参数直接记录下来,这种方法的优点是模拟结束后,所需要量测的数据已经完全记录下来,但缺点是要动到ns2核心的部分,对于初学者而言,这是一个很大的门坎,这个方法笔者留到后面的章节在做介绍。
笔者先对要模拟的环境做一个简单的介绍。这个网络的环境包含了四个网络节点(n0,n1,n2,n3),如下图所示。网络节点n0到节点n2之间,和节点n1到节点n2之间的网络频宽(bandwidth)是2Mbps,延迟时间(propagation delay)是10ms。网络拓朴中的频宽瓶颈是在节点n2到节点n3之间,频宽为1.7Mbps,延迟的时间为20ms。每个网络节都是采用DropTail queue的方式,且在节点n2到节点n3之间的最大队列长度是10个封包的长度。在节点n0到n3之间会有一条FTP的联机,FTP应用程序是架构在TCP之上,所以在写仿真环境的描述语言的时候,必需先建立一条TCP的联机,在来源端n0上使用TCP agent产生”tcp”来发送TCP的封包;在目的地端n3使用TCPsink agent产生”sink”来接受TCP的数据、并产生回复封包(ACK)回传送端、最后把接收的TCP封包释放。最后要把这两个agent连起来(connect),联机才能建立。若是没有额外的参数设定,TCP封包的长度为1Kbytes。在这里顺便补充说明一下,对于ns2模拟参数内定值设定是在ns-allinone-2.27\ns-2.27\tcl\lib目录下的ns-default.tcl,有想要进一步了解的人,可以去查看此档。另外,在节点n1到n3之间有一条固定的传输速率的联机(Constant Bit Rate,CBR),CBR应用程序是架构在UDP之上,因此必需在n1使用UDP agent来产生”udp”用来发送UDP封包,在n3上使用Null agent来产生”sink”以接收由n1传送过来的UDP封包,然后把接收的封包释放。CBR的传送速度为1Mbps,每一个封包大小为1Kbytes。CBR是在0.1秒开始传送,在4.5秒结束传输;FTP是在1.0秒开始传送,4.0秒结束传输。
[Simulation Topology]
[Tcl Script]
# 产生一个仿真的对象
set ns [new Simulator]
#针对不同的数据流定义不同的颜色,这是要给NAM用的
$ns color 1 Blue
$ns color 2 Red
#开启一个NAM trace file
set nf [open out.nam w]
$ns namtrace-all $nf
#开启一个trace file,用来记录封包传送的过程
set nd [open out.tr w]
$ns trace-all $nd
#定义一个结束的程序
proc finish {} {
global ns nf nd
$ns flush-trace
close $nf
close $nd
#以背景执行的方式去执行NAM
exec nam out.nam &
exit 0
}
#产生四个网络节点
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
#把节点连接起来
$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
#设定ns2到n3之间的Queue Size为10个封包大小
$ns queue-limit $n2 $n3 10
#设定节点的位置,这是要给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
#观测n2到n3之间queue的变化,这是要给NAM用的
$ns duplex-link-op $n2 $n3 queuePos 0.5
#建立一条TCP的联机
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
#在NAM中,TCP的联机会以蓝色表示
$tcp set fid_ 1
#在TCP联机之上建立FTP应用程序
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP
#建立一条UDP的联机
set udp [new Agent/UDP]
$ns attach-agent $n1 $udp
set null [new Agent/Null]
$ns attach-agent $n3 $null
$ns connect $udp $null
#在NAM中,UDP的联机会以红色表示
$udp set fid_ 2
#在UDP联机之上建立CBR应用程序
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
#设定FTP和CBR数据传送开始和结束时间
$ns at 0.1 "$cbr start"
$ns at 1.0 "$ftp start"
$ns at 4.0 "$ftp stop"
$ns at 4.5 "$cbr stop"
#结束TCP的联机(不一定需要写下面的程序代码来实际结束联机)
$ns at 4.5 "$ns detach-agent $n0 $tcp ; $ns detach-agent $n3 $sink"
#在模拟环境中,5秒后去呼叫finish来结束模拟(这样要注意模拟环境中
#的5秒并不一定等于实际模拟的时间
$ns at 5.0 "finish"
#执行模拟
$ns run
模拟结束后,会产生两个档案,一个是out.nam,这是给NAM用的,用来把模拟的过程用可视化的方式呈现出来,这可以让使用者用”看”的方式去了解封包传送是如何从来源端送到接收端。另一个档案是out.tr,这个档案记录了仿真过程中封包传送中所有的事件,例如第一笔记录是一个CBR的封包,长度为1000bytes,在时间0.1秒的时候,从n1传送到n2。这个档案对我们做效能分析很重要,所以要先对这个档案的格式做仔细的介绍。
+ 0.1 1 2 cbr 1000 ------- 2 1.0 3.1 0 0
- 0.1 1 2 cbr 1000 ------- 2 1.0 3.1 0 0
+ 0.108 1 2 cbr 1000 ------- 2 1.0 3.1 1 1
- 0.108 1 2 cbr 1000 ------- 2 1.0 3.1 1 1
r 0.114 1 2 cbr 1000 ------- 2 1.0 3.1 0 0
+ 0.114 2 3 cbr 1000 ------- 2 1.0 3.1 0 0
- 0.114 2 3 cbr 1000 ------- 2 1.0 3.1 0 0
+ 0.116 1 2 cbr 1000 ------- 2 1.0 3.1 2 2
- 0.116 1 2 cbr 1000 ------- 2 1.0 3.1 2 2
r 0.122 1 2 cbr 1000 ------- 2 1.0 3.1 1 1
+ 0.122 2 3 cbr 1000 ------- 2 1.0 3.1 1 1
.................................................................
每一笔记录的开始都是封包事件发生的原因,若是r则表示封包被某个节点所接收,若是+则表示进入了队列,若是-则表示离开队列,若是d则表示封包被队列所丢弃。接着的第二个字段表示的是事件发生的时间;字段三和字段四表示事件发生的地点(从from node到to node);字段五表示封包的型态;字段六是封包的大小,字段七是封包的旗标标注;字段八表示封包是属于那一个资料流;字段九和字段十是表示封包的来源端和目的端,这两个字段的格式是a.b,a代表节点编号,b表示埠号(port number);字段十一表示封包的序号;最后字段十二表示封包的id。以前面trace file的第一笔为例,意思就是说有一个封包pakcet id为0,资料流id为2,序号为0,长度为1000 bytes,型态为CBR,它是从来源端1.0要到目的地3.1,在时间0.1秒的时候,从节点1进入了节点2的队列中。
接下来,笔者先简单介绍awk,然后如何使用awk去分析trace file,以得到Throughput、Delay、Jitter、和Loss Rate。
[awk]
A.简介
awk是一种程序语言。它具有一般程序语言常见的功能。因awk语言具有某些特点,如:使用直译器(Interpreter)不需先行编译;变量无型别之分(Typeless),可使用文字当数组的注标(Associative Array)等特色。因此,使用awk撰写程序比起使用其它语言更简洁便利且节省时间。awk还具有一些内建功能,使得awk擅于处理具数据列(Record),字段(Field)型态的数据;此外, awk内建有pipe的功能,可将处理中的数据传送给外部的 Shell命令加以处理, 再将Shell命令处理后的数据传回awk程序,这个特点也使得awk程序很容易使用系统资源。
B. awk是如何运作的
为便于解释awk程序架构,以及相关的术语,笔者就以上面trace file为例,来加以介绍。
a.名词定义:
1. 资料列:awk从数据文件上读取的基本单位,以trace file为例,awk读入的
第一笔资料列为 ”+ 0.1 1 2 cbr 1000 ------- 2 1.0 3.1 0 0”
第二笔资料列为 “- 0.1 1 2 cbr 1000 ------- 2 1.0 3.1 0 0”
一般而言,一笔数据列相当于数据文件上的一行资料。
2. 字段(Field):为数据列上被分隔开的子字符串。
以资料列”+ 0.1 1 2 cbr 1000 ------- 2 1.0 3.1 0 0”为例,
一
二
三
四
五
六
七
八
九
十
十一
十二
+
0.1
1
2
cbr
1000
-------
2
1.0
3.1
0
0
一般而言是以空格符来分隔相邻的字段。
当awk读入数据列后,会把每个字段的值存入字段变量。
字段变量
意义
$0
为一字符串, 其内容为目前awk所读入的资料列.
$1
代表 $0 上第一个字段的数据.
$2
代表 $0 上第二栏个位的资料.
……
……
b.程序主要节构:
Pattern1 { Actions1 }
Pattern2 { Actions2 }
……………………………
Pattern3 { Actions3 }
一般常用”关系判断式”来当成Pattern。例如:
x > 3 用来判断变量x是否大于3
x == 5 用来判断变量x是否等于5
awk提供c语言常见的关系操作数,如:>、<、>=、<=、==、!=等等
Actions是由许多awk指令所构成,而awk的指令与c语言中的指令非常类似。
IO指令:print 、 printf( ) 、getline ......
流程控制指令 : if ( ...) {...} else {…}、 while(…){…} ……
在awk程序的流程为先判断Pattern的结果,若为真True则执行相对应的Actions,若为假False则不执行相对的Actions。若是处理的过程中没有Pattern,awk会无条件的去执行Actions。
c.工作流程: 执行awk时, 它会反复进行下列四步骤。
1. 自动从指定的数据文件中读取一笔数据列。
2. 自动更新(Update)相关的内建变量之值。
3. 逐次执行程序中 所有 的 Pattern { Actions } 指令。
4. 当执行完程序中所有 Pattern { Actions }时,若数据文件中还有未读取的料,则反复执行步骤1到步骤4。
awk会自动重复进行上述的四个步骤,所以使用者不须在程序中写这个循环。
[End-to-End Delay]
笔者把量测CBR封包端点到端点间延迟时间的awk程序,写在档案measure-delay.awk档案中,读者可以参考此范例,修改成符合读者需求的程序。
BEGIN {
#程序初始化,设定一变量以记录目前最高处理封包的ID。
highest_packet_id = 0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
type = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#记录目前最高的packet ID
if ( packet_id > highest_packet_id )
highest_packet_id = packet_id;
#记录封包的传送时间
if ( start_time[packet_id] == 0 )
start_time[packet_id] = time;
#记录CBR (flow_id=2) 的接收时间
if ( flow_id == 2 && action != "d" ) {
if ( action == "r" ) {
end_time[packet_id] = time;
}
} else {
#把不是flow_id=2的封包或者是flow_id=2但此封包被drop的时间设为-1
end_time[packet_id] = -1;
}
}
END {
#当数据列全部读取完后,开始计算有效封包的端点到端点延迟时间
for ( packet_id = 0; packet_id <= highest_packet_id; packet_id++ ) {
start = start_time[packet_id];
end = end_time[packet_id];
packet_duration = end - start;
#只把接收时间大于传送时间的记录列出来
if ( start < end ) printf("%f %f\n", start, packet_duration);
}
}
执行方法: ($为shell的提示符号)
$awk -f measure-delay.awk out.tr
若是要把结果存到档案,可使用导向的方式。(把结果存到cbr_delay档案中)
$awk -f measure-delay.awk out.tr > cbr_delay
执行结果:
0.100000 0.038706
0.108000 0.038706
0.116000 0.038706
0.124000 0.038706
0.132000 0.038706
………………………
[Jitter]
Jitter就是延迟时间变化量delay variance,由于网络的状态随时都在变化,有时候流量大,有时候流量小,当流量大的时候,许多封包就必需在节点的队列中等待被传送,因此每个封包从传送端到目的地端的时间不一定会相同,而这个不同的差异就是所谓的Jitter。Jitter越大,则表示网络越不稳定。笔者把量测CBR flow的Jitter的awk写在档案measure-jitter.awk内。
BEGIN {
#程序初始化
old_time=0;
old_seq_no=0;
i=0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
type = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#判断是否为n2传送到n3,且封包型态为cbr,动作为接受封包
if(node_1==2 && node_2==3 && type=="cbr" && action=="r") {
#求出目前封包的序号和上次成功接收的序号差值
dif=seq_no-old_seq_no;
#处理第一个接收封包
if(dif==0)
dif=1;
#求出jitter
jitter[i]=(time-old_time)/dif;
seq[i]=seq_no;
i=i+1;
old_seq_no=seq_no;
old_time=time;
}
}
END {
for (j=1; j <i ;j++)
printf("%d\t%f\n",seq[j],jitter[j]);
}
执行方法: ($为shell的提示符号)
$awk -f measure-jitter.awk out.tr
若是要把结果存到档案,可使用导向的方式。(把结果存到cbr_jitter档案中)
$awk -f measure-jitter.awk out.tr > cbr_jitter
执行结果:
1 0.008000
2 0.008000
3 0.008000
4 0.008000
……………………
[另一种计算Jitter的方法---更精确的方式]
# == Usage ==
# awk -f NormalJitter.awk out.tr
# == Description ==
# 本awk程序给出了另外一种jitter的计算方法,这种方法中jitter的计算是基于以下公式:
# jitter =((recvtime(j)-sendtime(j))-(recvtime(i)-sendtime(i)))/(j-i), 其中 j>i 。
# == Attention ==
# NormalJitter.awk中关于jitter的计算完全基于柯志亨博士的measure-delay.awk程序中delay的
# 计算。而measure-delay.awk在柯博士网页中的ns2模拟例子中是正确的,但是对于不同的例子需要根
# 据情况进行一定的修改,并可能需要加入某些鲁棒性处理代码(例如对于第一个包的处理,对于丢包的处
# 理等)。
BEGIN {
#程序初始化,设定一变量以记录目前最高处理封包的ID。
highest_packet_id = 0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
type = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#记录目前最高的packet ID
if ( packet_id > highest_packet_id ) {
highest_packet_id = packet_id;
}
#记录封包的传送时间
if ( start_time[packet_id] == 0 ) {
# 记录下包的seq_no -- ZHA
pkt_seqno[packet_id] = seq_no;
start_time[packet_id] = time;
}
#记录CBR (flow_id=2) 的接收时间
if ( flow_id == 2 && action != "d" ) {
if ( action == "r" ) {
end_time[packet_id] = time;
}
} else {
#把不是flow_id=2的封包或者是flow_id=2但此封包被drop的时间设为-1
end_time[packet_id] = -1;
}
}
END {
# 初始化jitter计算所需变量 -- ZHA
last_seqno = 0;
last_delay = 0;
seqno_diff = 0;
#当数据列全部读取完后,开始计算有效封包的端点到端点延迟时间
for ( packet_id = 0; packet_id <= highest_packet_id; packet_id++ ) {
start = start_time[packet_id];
end = end_time[packet_id];
packet_duration = end - start;
#只把接收时间大于传送时间的记录列出来
if ( start < end ) {
# 得到了delay值(packet_duration)后计算jitter -- ZHA
seqno_diff = pkt_seqno[packet_id] - last_seqno;
delay_diff = packet_duration - last_delay;
if (seqno_diff == 0) {
jitter =0;
} else {
jitter = delay_diff/seqno_diff;
}
printf("%f %f\n", start, jitter);
last_seqno = pkt_seqno[packet_id];
last_delay = packet_duration;
}
}
}
[Loss]
笔者把量测CBR Packet Loss的情况写在档案measure-drop.awk内。
BEGIN {
#程序初始化,设定一变量记录packet被drop的数目
fsDrops = 0;
numFs = 0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
src = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#统计从n1送出多少packets
if (node_1==1 && node_2==2 && action == "+")
numFs++;
#统计flow_id为2,且被drop的封包
if (flow_id==2 && action == "d")
fsDrops++;
}
END {
printf("number of packets sent:%d lost:%d\n", numFs, fsDrops);
}
执行方法: ($为shell的提示符号)
$awk -f measure-drop.awk out.tr
执行结果:
number of packets sent: 550 lost:8
这代表CBR送出了550个封包,但其中8个封包丢掉了。
[Throughput]
笔者把量测CBR Throughput的情况写在档案measure-throughput.awk内。在这里的Throughput是指average throughput。
BEGIN {
init=0;
i=0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
src = $5;
pktsize = $6;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
if(action=="r" && node_1==2 && node_2==3 && flow_id==2) {
pkt_byte_sum[i+1]=pkt_byte_sum[i]+ pktsize;
if(init==0) {
start_time = time;
init = 1;
}
end_time[i] = time;
i = i+1;
}
}
END {
#为了画图好看,把第一笔记录的throughput设为零,以表示传输开始
printf("%.2f\t%.2f\n", end_time[0], 0);
for(j=1 ; j<i ; j++){
th = pkt_byte_sum[j] / (end_time[j] - start_time)*8/1000;
printf("%.2f\t%.2f\n", end_time[j], th);
}
#为了画图好看,把第后一笔记录的throughput再设为零,以表示传输结束
printf("%.2f\t%.2f\n", end_time[i-1], 0);
}
执行方法: ($为shell的提示符号)
$awk -f measure-throughput.awk out.tr
若是要把结果存到档案,可使用导向的方式。(把结果存到cbr_throughput档案中)
$awk -f measure-throughput.awk out.tr > cbr_throughput
执行结果:
0.14 0.00
0.15 1000.00
0.15 1000.00
0.16 1000.00
……………………
介绍完了如何量测End-to-End Delay、Jitter、Packet Loss、和Throughput后,最后就是要把量测的数据画出来。这里笔者介绍xgraph和gnuplot,但是xgraph画出来的图真的有点丑,所以就不仔细介绍。笔者会把重心放在gnuplot。
[xgraph]
在Shell的提示符号后输入startxwin.bat,接着会出现一个新的窗口,在此窗口输入xgraph cbr_delay,就可以把前面所存下来的档案画出来。xgraph的运作是把第一排当作x轴的数据,第二排当作是y轴的数据,然后把图给画出来。
cbr-delay的图:
在一刚开始的时候,由于只有CBR的封包,所以End-to-End Delay Time都是固定的,但在1.0秒后,网络多了FTP的封包,这使得CBR封包和FTP封包必须互相的抢夺网络的资源,因此End-to-End Delay Time变得不在固定,但等到FTP传输结束后,CBR封包的End-to-End Delay Time又变成是固定值了。
cbr-jitter的图:
Jitter的变化情况跟End-to-End的原因是相同的,都是由于FTP封包的加入才会指得End-to-End Delay Time会产生变化。
cbr-throughput的图:
从图可以很清楚地看出,从0.1秒到4.5秒,CBR的传输速率大都维持在1Mbps。
看了上面这三张图,不知道读者是否有一种感觉,就是真的有点丑。是不是想换个工具呢?用Excel吗?笔者认为还是一样丑,所以笔者强力推荐使用接下来要介绍的gnuplot。
[gnuplot]
A. 简介
gnuplot 是一个命令导向的交谈式绘图程序(command-driven interactive function plotting program)。使用者输入的每一项命令,可以逐步设定或
修改绘图环境。它以图形表达数据或涵数,使我们可以藉由图形做更进一步的分析。
B. 如何使用gnuplot ($为cygwin shell的提示符号)
a. $ startxwin.bat
b. 在新开出来的窗口输入gnuplot
$gnuplot
c. 执行 GNUPLOT 程序时,GNUPLOT 首先检查是否设定环境参数 DISPLAY, 若有则依其设定。当其确定为 X 环境时,将输出模式设定为 X11。笔者以cbr_delay为例,先简单示范如何把图给画出来。画图的指令是plot,要画的档案cbr_delay。
gnuplot> plot “cbr_delay”
图是画出来了,但是笔者要的不是把数据用打点的方式画出来,而是要把这些点连起来。没关系,接下来,只要学着修改环境变量,就可以画出理想的图了。
C. 修改环境变量
a.坐标轴(Axis):绘图参数在设定坐标轴方面的参数可分为变量名称、标点、网格、显示范围、 坐标轴显示方式与显示与否等六方面的设定。不过笔者只介绍几个常用的设定,详细的设定可以参考http://phi.sinica.edu.tw/aspac/reports/94/94002/。
功能
绘图参数名称
标点设定
xtics,ydtics
网格设定
grid
坐标显示方式
logscale
显示范围设定
autoscale,xr
展开阅读全文