版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
使用一些工具来分析和呈现模拟结果对于使用网络仿真软件来做网络效能分析的人而言,步骤通常是先设计出符合自己需要的网络仿真环境,设定其不同的参数,执行仿真,收集结果数据,最后把数据使用图片或表格把结果呈现出来以方便分析实验。一般而言,对于ns2的初学者而言,总是会遇到一个问题,就是网络仿真程序跑完后,接下来该如何分析。这是非常重要的一个过程,所以希望ns2的初学者能好好的研究此章节的内容,相信一定会对大家的研究有相当的帮助。本节打算以一个简单的网络环境为范例,介绍如何使用一些工具来分析和呈现模拟结果,这包含了如何去量测End-to-EndDelay、Jitter、PacketLoss、和Throughput。而采用的方法是去分析traffictrace档案的方式,这种方法的优点是简单且不需要去修改到ns2核心的部份,但缺点是若是仿真数据若是太多,traffictrace的档案会太大,这样会增加分析所需要的时间。另外一种方法,是去更改ns2核心,增加或修改一些档案,把所需要量测的参数直接记录下来,这种方法的优点是模拟结束后,所需要量测的数据已经完全记录下来,但缺点是要动到ns2核心的部分,对于初学者而言,这是一个很大的门坎,这个方法笔者留到后面的章节在做介绍。笔者先对要模拟的环境做一个简单的介绍。这个网络的环境包含了四个网络节点(nO,n1,n2,n3),如下图所示。网络节点n0到节点n2之间,和节点n1到节点n2之间的网络频宽(bandwidth)是2Mbps,延迟时间(propagationdelay)是10ms。网络拓朴中的频宽瓶颈是在节点n2到节点n3之间,频宽为1.7Mbps,延迟的时间为20ms。每个网络节都是采用DropTailqueue的方式,且在节点n2到节点n3之间的最大队列长度是10个封包的长度。在节点n0到n3之间会有一条FTP的联机,FTP应用程序是架构在TCP之上,所以在写仿真环境的描述语言的时候,必需先建立一条TCP的联机,在来源端n0上使用TCPagent产生”tcp”来发送TCP的封包;在目的地端n3使用TCPsinkagent产生”sink”来接受TCP的数据、并产生回复封包(ACK)回传送端、最后把接收的TCP封包释放。最后要把这两个agent连起来(connect),联机才能建立。若是没有额外的参数设定,TCP封包的长度为1Kbytes。在这里顺便补充说明一下,对于ns2模拟参数内定值设定是在ns-allinone-2.27\ns-2.27\tcl\lib目录下的ns-default.tcl,有想要进一步了解的人,可以去查看此档。另外,在节点n1到n3之间有一条固定的传输速率的联机(ConstantBitRateCBR),CBR应用程序是架构在UDP之上,因此必需在n1使用UDPagent来产生”udp”用来发送UDP封包,在n3上使用Nullagent来产生”sink”以接收由n1传送过来的UDP封包,然后把接收的封包释放。CBR的传送速度为1Mbps,每一个封包大小为1Kbytes。CBR是在0.1秒开始传送,在4.5秒结束传输;FTP是在1.0秒开始传送,4.0秒结束传输。[SimulationTopology]11卜*404511卜*4045[TelScript]#产生一个仿真的对象setns[newSimulator]#针对不同的数据流定义不同的颜色,这是要给NAM用的$nscolor1Blue$nscolor2Red#开启一个NAMtracefilesetnf[openout.namw]$nsnamtrace-all$nf#开启一个tracefile,用来记录封包传送的过程setnd[openout.trw]$nstrace-all$nd#定义一个结束的程序procfinish{}{globalnsnfnd$nsflush-traceclose$nfclose$nd#以背景执行的方式去执行NAMexecnamout.nam&exit0}#产生四个网络节点setnO[$nsnode]setn1[$nsnode]setn2[$nsnode]setn3[$nsnode]#把节点连接起来$nsduplex-link$n0$n22Mb10msDropTail$nsduplex-link$n1$n22Mb10msDropTail$nsduplex-link$n2$n31.7Mb20msDropTail#设定ns2到n3之间的QueueSize为10个封包大小$nsqueue-limit$n2$n310#设定节点的位置,这是要给NAM用的$nsduplex-link-op$n0$n2orientright-down$nsduplex-link-op$n1$n2orientright-up$nsduplex-link-op$n2$n3orientright#观测n2到n3之间queue的变化,这是要给NAM用的$nsduplex-link-op$n2$n3queuePos0.5#建立一条TCP的联机settcp[newAgent/TCP]$tcpsetclass_2$nsattach-agent$n0$tcpsetsink[newAgent/TCPSink]$nsattach-agent$n3$sink$nsconnect$tcp$sink#在NAM中,TCP的联机会以蓝色表示$tcpsetfid_1#在TCP联机之上建立FTP应用程序setftp[newApplication/FTP]$ftpattach-agent$tcp
$ftpsettype_FTP#建立一条UDP的联机setudp[newAgent/UDP]$nsattach-agent$n1$udpsetnull[newAgent/Null]$nsattach-agent$n3$null$nsconnect$udp$null#在NAM中,UDP的联机会以红色表示$udpsetfid_2#在UDP联机之上建立CBR应用程序setcbr[newApplication/Traffic/CBR]$cbrattach-agent$udp$cbrsettype_CBR$cbrsetpacket_size_1000$cbrsetrate_1mb$cbrsetrandom_false#设定FTP和CBR数据传送开始和结束时间$nsat0.1"$cbrstart"$nsat1.0"$ftpstart"$nsat4.0"$ftpstop"$nsat4.5"$cbrstop"#结束TCP的联机(不一定需要写下面的程序代码来实际结束联机)$nsat4.5"$nsdetach-agent$n0$tcp;$nsdetach-agent$n3$sink"#在模拟环境中,5秒后去呼叫finish来结束模拟(这样要注意模拟环境中#的5秒并不一定等于实际模拟的时间$nsat5.0"finish"#执行模拟EMNAMThENdWOrflAiiauHla^*1.1«NAM-TheNetworkAnimator呼I阪叫厕-IrH-5ip.p]SitclEMNAMThENdWOrflAiiauHla^*1.1«NAM-TheNetworkAnimator呼I阪叫厕-IrH-5ip.p]Sitcl-1512111|丄1.山1」」儿日.1匚1|1|1丨丨iiihiiiiiHniHirnri33甜WWctmwtoHflm1JIDu*血byUCDandifiu^IHT.SAMAM,und5生erpruj氓阿皿ISIHnmcwitRinjf口jdfiwithllwcnfi寸醴的co^yrfi)ht(t)lUJilUM-iReyetio-fthwUniversityorc^TcHiid.Cop®州||战fcj1997-1bilwsEtyofSm腑BmCaflfenilftOpynght(n)ZIIIBI7CMPurit/mrnninH.liMiHnunii:酣Instjtills模拟结束后,会产生两个档案,一个是out.nam,这是给NAM用的,用来把模拟的过程用可视化的方式呈现出来,这可以让使用者用〃看〃的方式去了解封包传送是如何从来源端送到接收端。另一个档案是out.tr,这个档案记录了仿真过程中封包传送中所有的事件,例如第一笔记录是一个CBR的封包,长度为1000bytes,在时间0.1秒的时候,从n1传送到n2。这个档案对我们做效能分析很重要,所以要先对这个档案的格式做仔细的介绍。+0.112cbr100021.03.100一0.112cbr100021.03.100+0.10812cbr100021.03.111一0.10812cbr100021.03.111r0.11412cbr100021.03.100+0.11423cbr100021.03.100一0.11423cbr100021.03.100+0.11612cbr100021.03.122一0.11612cbr100021.03.122r0.12212cbr100021.03.111+0.12223cbr100021.03.111ftdisrIsxldrIIr:receive(at+:(blar^addinude.口口工呂-:中巳tiu匕E亡(attn■腥诵0:口Bde.pOEl(审・0]d:drop(acqweuc)每一笔记录的开始都是封包事件发生的原因,若是r则表示封包被某个节点所接收,若是+则表示进入了队列,若是-则表示离开队列,若是d则表示封包被队列所丢弃。接着的第二个字段表示的是事件发生的时间;字段三和字段四表示事件发生的地点(从fromnode到tonode);字段五表示封包的型态;字段六是封包的大小,字段七是封包的旗标标注;字段八表示封包是属于那一个资料流;字段九和字段十是表示封包的来源端和目的端,这两个字段的格式是a.b,a代表节点编号,b表示埠号(portnumber);字段^一表示封包的序号;最后字段十二表示封包的id。以前面tracefile的第一笔为例,意思就是说有一个封包pakcetid为0,资料流id为2,序号为0,长度为1000bytes,型态为CBR,它是从来源端1.0要到目的地3.1,在时间0.1秒的时候,从节点1进入了节点2的队列中。接下来,笔者先简单介绍awk,然后如何使用awk去分析tracefile,以得到Throughput、Delay、Jitter、和LossRate。[awk]简介awk是一种程序语言。它具有一般程序语言常见的功能。因awk语言具有某些特点,如:使用直译器(Interpreter)不需先行编译;变量无型别之分(Typeless),可使用文字当数组的注标(AssociativeArray)等特色。因此,使用awk撰写程序比起使用其它语言更简洁便利且节省时间。awk还具有一些内建功能,使得awk擅于处理具数据列(Record),字段(Field)型态的数据;此外,awk内建有pipe的功能,可将处理中的数据传送给外部的Shell命令加以处理,再将Shell命令处理后的数据传回awk程序,这个特点也使得awk程序很容易使用系统资源。awk是如何运作的为便于解释awk程序架构,以及相关的术语,笔者就以上面tracefile为例,来加以介绍。a.名词定义:资料列:awk从数据文件上读取的基本单位,以tracefile为例,awk读入的第一笔资料列为〃+0.112cbr100021.03.100〃第二笔资料列为“一0.112cbr100021.03.100”一般而言,一笔数据列相当于数据文件上的一行资料。字段(Field):为数据列上被分隔开的子字符串。以资料列”+0.112cbr100021.03.100”为例,-一一二三四五六七八九十十一十二+0.112cbr10021.03.1000--一般而言是以空格符来分隔相邻的字段。当awk读入数据列后,会把每个字段的值存入字段变量。字段变量意义$0为一字符串,其内容为目前awk所读入的资料列.$1代表$0上第一个字段的数据.$2代表$0上第二栏个位的资料.b■程序主要节构:Pattern1{Actions1}Pattern2{Actions2}Pattern3{Actions3}一般常用〃关系判断式〃来当成Pattern。例如:x>3用来判断变量x是否大于3x==5用来判断变量x是否等于5awk提供c语言常见的关系操作数,如:〉、<、>=、<=、==、!=等等Actions是由许多awk指令所构成,而awk的指令与c语言中的指令非常类似。10指令:print、printf()、getline流程控制指令:if(…){...}else{...}、while(...){...}……在awk程序的流程为先判断Pattern的结果,若为真True则执行相对应的Actions,若为假False则不执行相对的Actions。若是处理的过程中没有Pattern,awk会无条件的去执行Actions。c■工作流程:执行awk时,它会反复进行下列四步骤。自动从指定的数据文件中读取一笔数据列。自动更新(Update)相关的内建变量之值。逐次执行程序中所有的Pattern{Actions}指令。当执行完程序中所有Pattern{Actions}时,若数据文件中还有未读取的料,则反复执行步骤1到步骤4。awk会自动重复进行上述的四个步骤,所以使用者不须在程序中写这个循环。[End-to-EndDelay]笔者把量测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;#记录目前最高的packetIDif(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的时间设为-1end_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-fmeasure-delay.awkout.tr若是要把结果存到档案,可使用导向的方式。(把结果存到cbr_delay档案中)$awk-fmeasure-delay.awkout.tr>cbr_delay执行结果:0.1000000.0387060.1080000.0387060.1160000.0387060.1240000.0387060.1320000.038706[Jitter]Jitter就是延迟时间变化量delayvarianee,由于网络的状态随时都在变化,有时候流量大,有时候流量小,当流量大的时候,许多封包就必需在节点的队列中等待被传送,因此每个封包从传送端到目的地端的时间不一定会相同,而这个不同的差异就是所谓的Jitter。Jitter越大,则表示网络越不稳定。笔者把量测CBRflow的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;#求出jitterjitter[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-fmeasure-jitter.awkout.tr若是要把结果存到档案,可使用导向的方式。(把结果存到cbr_jitter档案中)$awk-fmeasure-jitter.awkout.tr>cbr_jitter执行结果:12340.00800012340.0080000.0080000.008000[另一种计算Jitter的方法—更精确的方式]==Usage==awk-fNormalJitteuawkout.tr==Description==#本awk程序给出了另外一种jitter的计算方法,这种方法中jitter的计算是基于以下公式:jitter=((recvtime(j)-sendtime(j))-(recvtime(i)-sendtime(i)))/(j-i),其中j>i。==Attention==NormalJitterawk中关于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;#记录目前最高的packetIDif(packet_id>highest_packet_id){highest_packet_id=packet_id;}#记录封包的传送时间if(start_time[packet_id]==0){#记录下包的seq_no--ZHApkt_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的时间设为-1end_time[packet_id]=-1;}}END{#初始化jitter计算所需变量--ZHAlast_seqno=0;last_delay=0;seqno_diff=0;#当数据列全部读取完后,开始计算有效封包的端点到端点延迟时间for(packet_id=0;packet_id<=highest_packet_id;packet_id++){start=starttime[packetid];end=end_time[packet_id];packet_duration=end-start;#只把接收时间大于传送时间的记录列出来if(start<end){#得到了delay值(packet_duration)后计算jitter--ZHAseqno_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]笔者把量测CBRPacketLoss的情况写在档案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送出多少packetsif(node_1==1&&node_2==2&&action=="+")numFs++;#统计flow_id为2,且被drop的封包if(flow_id==2&&action=="d")fsDrops++;}END{printf("numberofpacketssent:%dlost:%d\n",numFs,fsDrops);}执行方法:($为shell的提示符号)$awk-fmeasure-drop.awkout.tr执行结果:numberofpacketssent:550lost:8这代表CBR送出了550个封包,但其中8个封包丢掉了。[Throughput]笔者把量测CBRThroughput的情况写在档案measure-throughput.awk内。在这里的Throughput是扌旨averagethroughput。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-fmeasure-throughput.awkout.tr若是要把结果存到档案,可使用导向的方式。(把结果存到cbr_throughput档案中)$awk-fmeasure-throughput.awkout.tr>cbr_throughput执行结果:0.140.000.151000.000.151000.000.161000.00
介绍完了如何量测End-to-EndDelay、Jitter、PacketLoss、和Throughput后,最后就是要把量测的数据画出来。这里笔者介绍xgraph和gnuplot,但是xgraph画出来的图真的有点丑,所以就不仔细介绍。笔者会把重心放在gnuplot。[xgraph]在Shell的提示符号后输入startxwin.bat,接着会出现一个新的窗口,在此窗口输入xgraphcbr_delay,就可以把前面所存下来的档案画出来。xgraph的运作是把第一排当作x轴的数据,第二排当作是y轴的数据,然后把图给画出来。cbrdelay的图:在一刚开始的时候,由于只有CBR的封包,所以End-to-EndDelayTime都是固定的,但在1.0秒后,网络多了FTP的封包,这使得CBR封包和FTP封包必须互相的抢夺网络的资源,因此End-to-EndDelayTime变得不在固定,但等到FTP传输结束后,CBR封包的End-to-EndDelayTime又变成是固定值了。cbrjitter的图:Jitter的变化情况跟End-to-End的原因是相同的,都是由于FTP封包的加入才会指得End-to-EndDelayTime会产生变化。cbrthroughput的图:滋、滋、xgraphEBE从图可以很清楚地看出,从0.1秒到4.5秒,CBR的传输速率大都维持在1Mbps。看了上面这三张图,不知道读者是否有一种感觉,就是真的有点丑。是不是想换个工具呢?用Excel吗?笔者认为还是一样丑,所以笔者强力推荐使用接下来要介绍的gnuplot。[gnuplot]A.简介gnuplot是一个命令导向的交谈式绘图程序(command-driveninteractivefunctionplottingprogram)。使用者输入的每一项命令,可以逐步设定或修改绘图环境。它以图形表达数据或涵数,使我们可以藉由图形做更进一步的分析。B.如何使用gnuplot($为cygwinshell的提示符号)a.$startxwin.batb.在新开出来的窗口输入gnuplot$gnuplotnNUPL0TYstthmJiBljMtchlfl-sfl!!]0Iw.tnrdLhedL.tidHer』27GUT2«C!刖丸刑r.TftHH.HT-fi.L=連左打匸甲勺們ght』匸)1SBE-1999-ThOhHdLI.]L^lr;>l_h)LnKbHajJ"d心问Tfd:s佔aofcr*丄就4,d.,PI-mm-referbotr亡d^LMiitatlcdifa--cuhhaid古屮丈吃T卜亡aid远鬥込idlJLbe-xg3dtlYcti^-uutthe+.0serL"一bJthi]imum-U-tTjp«'htLp't&aoccDStiton-LineK<KerBt<tnaruaLThe-gnupLatFHUM.awnLabL匕fraihttp£//HiAj+y*JpLirtrInfnz'-T呵5nxi匚qtM咼ad“^比三forhelpg<Snfo-gnypLoi:-_lMii:>^3dflrt*DUi:h.rdu'--bvgsr®VKP5tlorfl:ad■od?ta<ln<-D-grT.jplot-hrt-Akrtwrth上出0T*t・】m]坠”?Bt-S'rd!'grxjp]°k>■c.执行GNUPLOT程序时,GNUPLOT首先检查是否设定环境参数DISPLAY,若有则依其设定。当其确定为X环境时,将输出模式设定为X11。笔者以cbr_delay为例,先简单示范如何把图给画出来。画图的指令是plot,要画的档案cbr_delay。gnuplot〉plot“cbr_delay”图是画出来了,但是笔者要的不是把数据用打点的方式画出来,而是要把这些点连起来。没关系,接下来,只要学着修改环境变量,就可以画出理想的图了。C.修改环境变量a・坐标轴(Axis):绘图参数在设定坐标轴方面的参数可分为变量名称、标点、网格、显示范围、坐标轴显示方式与显示与否等六方面的设定。不过笔者只介绍几个常用的设定,详细的设定可以参考.tw/aspac/reports/94/94002/。功能绘图参数名称标点设定xtics,ydtics网格设定grid坐标显示方式logscale显示范围设定autoscale,xrange,yrange坐标轴显示与否xzeroaxis,yzeroaxis说明:xtics是对X坐标轴上的标点做设定。如起始点、结束点、间隔或在轴上特定点放特定的名称。其语法为:setxtics{{vstart>,vincr>{,vend>}}|{({"vlabel〉"}vpos>{,{"vlabel>"}vpos>}…)}}unsetxtics#不标示任何X轴上的标点。showxtics#显示X轴标点的状况。例:(原本)gnuplot>plotsin(x)
在x轴上的标点设定是以5为单位。若是觉得想要把标点距离设小一点,例如设为1可以使用gnuplot>setxtics-10,1,10gnuplot>plotsin(x)ytics与xtics相似,不同点是作用在y轴上。网格设定:在XY坐标平面上依刻度画上方格子。gnuplot>setgridgnuplot>plotsin(x)若是想要把网格拿掉,只要在下unsetgrid即可。坐标显示方式:分为线性与对数两种。一般为前者,若要改为对数方式,其语法为:setlogscale<axes>vbase>其中axes为X轴、Y轴、Z轴的任意组合。base预设为10。显示范围设定:改变各轴的显示范围。autoscale参数设定后gnuplot自动调整显示范围。而xrange、yrange则是可以由使用者设定该轴的范围。以xrange为例,其语法为:setxrange[{vxmin>:vxmax>}]其中参数vxmin>与vxmax>代表X轴的起点与终点,可以是数字或数学式子。例:gnuplot>setxrange[0:10]gnuplot>plotsin(x)!!BlipIniSOB侮轴口如J?秀5.坐标轴显示与否设定侮轴口如J?秀5.坐标轴显示与否设定:设定是否要画出坐标轴,以X轴为例:#设定显示X坐标轴#设定不显示X坐标轴#检查X坐标轴显示与否若是要把xzeroaxis拿掉,只要下unsetxzeroaxis即可。setxzeroaxisunsetxzeroaxisshowxzeroaxisgnuplot>setxzeroaxisgnuplot>plotsin(x)b■标示(Label):GNUPLOT除了绘出图形外,尚可加入批注做为辅助说明。这批注包括文字与线条两方面,其提供的设定有功能绘图参数名称线条arrow文字批注key,label,title,xlabel,ylabel说明:1.线条:在图上画一线段可以选择有无箭头。其语法为setarrow{<tag>}{fromvsx>,vsy>{,vsz>}}{tovex>,vey>{,vez>}}{{no}head}unsetarrow{vtag>}#删除一线条showarrow#显示线条使用情况其中参数vtag>是给该条线条一个整数名称,若不设定则为最小可用整数。此线条由坐标(sx,sy,sz倒(ex,ey,ez)(在2D中为(sx,sy)到(ex,ey))。参数nohead为画没有箭头的线段,参数head或没有nohead为画有箭头的线段。#画一带有箭头的线条由原点到(1,2)。gnuplot>setarrowto1,2#画一名为3的带箭头线条由(0.4,0.3)至I」(0.2,0.1)。gnuplot>setarrow3from0.4,0.3to0.2,0.1#删除名为3的线条。gnuplot>unsetarrow3#删除所有线条。guplot>unsetarrow2.文字批注:分为设定标头(title)和标示(label)。标头(title):设定为在图的正上方加上说明本图的文字。其语法为:settitle{"vtitle-text>"}{vxoff>}{,vyoff>}showtitle其中设定参数vxoff>或vyoff>为微调标头放置的地址。xlabel,ylabel的语法与title相同,其各自描述一坐标轴。标示(label):为在图上任一位置加上文字说明,一般与线条一并使用。setlabel{vtag>}{"vlabel_text>"}{atvx>,vy>{,vz>}}{vjustification>}unsetlabel{vtag>}#删除一标示showlabel#显示标示使用情况其中参数vtag>与"线条"(arrow)中vtag>意义相同,用以区别不同的label。参数vjustification>是调整文字放置的位置,可以是left,right或center。#将y=x放在坐标(1,2)之处。gnuplot〉setlabel“y=x"at1,2#将y=x^2放在坐标(2,3)之处,并命名为3。gnuplot>setlabel3"y=x^2"at2,3right#将名为3的标示居中放置。gnuplot>setlabel3center#删除名为3的标示。gnuplot>unsetlabel3#删除所有标示。gnuplot>unsellabel一般绘一图形后,gnuplot会将函数名称或图形文件名称置于右上角。key参数设定可改变名称放置位置。其语法为:setkeysetkeyvx>,vy>{,vz>}#其中参数vx>,vy>,vz>设定名称放置位置。unsetkey#不显示名称showkey#再度显示名称[例]gnuplot>settitle“cbr_delay"gnuplot>setxlabel“simulationtime"gnuplot>setylabel“delaytime"gnuplot>unsetkeygnuplot>setlabel“constantdelay=0.038706sec"at0.1,0.05gnuplot>setarrowfrom0.5,0.05to0.5,0.04滋滋GnuplotEBEooooo"■=4R-«p3.89224.085o7*oo+oooooo"■=4R-«p3.89224.085o7*oo+oc■图样(Style):gnuplot描绘数据数据图形是以读入档案中的坐标值后,以图样绘上。而描绘函数图形是计算若干点的函数值后,以某种图样将函数值绘上。一般是取样100点及采取线条作为图样。GNUPLOT可提供9种图样,分别是lines:将相邻的点以线条连接。如plotsin(x)withlines。points:将每一点以一符号绘上。如plotsin(x)withpointslinespoints:同时具有lines及points的功能。如plotsin(x)withlinespoints。impulses:将每一点画一垂直线至X轴。如plotsin(x)withimpulses。dots:将每一点绘一细点。如plotsin(x)withdots。steps:以垂直线及水平线各一条来连接两点,形成梯形。如连接(x1,y1),(x2,y2)两点,以(x1,y1)到(x2,y1)和(x2,y1)到(x2,y2)两线段连接。如plotsin(x)withsteps。errorbars:对每一点坐标值(x,y),画一由(x,ylow)至(x,yhigh)的线段。并在线段两端做上ticmark。如plotsin(x)witherrorbars。boxes:Theboxesstyledrawsaboxcentredaboutthegivenxcoordinatefromtheyaxistothegivenycoordinate.如plotsin(x)withboxes。boxerrorbars:组合errorbars与boxes两者功能。如plotsin(x)withboxerrorbars[例]把cbr_delay中的数据用lines和points连起来。gnuplot〉plot“cbr_delay”withlinespoints滋Gnuplot匚]叵]区|c:br_delay滋Gnuplot匚]叵]区|c:br_delay0+0850.0351■11■■1100+511+522+533.544+5simulationtime这个图有没有比用xgraph画出来的图好看呢?d■输出(Output):GNUPLOT的输出参数设定有terminal,output。不过在这里笔者只介绍如何把画出来的图存成Gif格式。#把输出设成存成gif格式,内定为X11terminalgnuplot>setterminalgif新增模块测量协议性能在本小节中,笔者将介绍如何在ns2核心中直接新增模块,以用来量测以UDP为传输协议的应用程序之OneWayDelay(OWD)、IPDelayVariance(IPDV,或是Jitter)和PacketLoss数量。使用这个方法的好处就是当模拟结束后,所需要的数据就直接存放到档案内,然后就可以直接进行分析。我们要采用的方法就是在封包的接收端去查看封包表头内的信息以计算出OWD、IPDV、或者是PacketLoss数量,其中最重要的信息就是SendingTime(传送时间)和SequeneeNumber(封包序号)。SendingTime可以用来计算出OWD和IPDV,计算的方式如下:OneWayDelay=接收时间-传送时间IPDV=|目前量测到的OWD-上一次量测到的OWD|而PacketLoss数量则可以由封包序号的不连续性所计算出,每一个封包在传送端发送前,传送端都会给封包一个序号,序号是连续性的,因此若是在接收到发现序号有不连续的发生,则可视为有封包的移失。(这边不考虑Out-of-Order情况)[方法]1.在NS2中,在RTP表头中已经有序号的字段。目前第一步要做的就是去增加一个SendingTime的字段,并且当封包在传送端发送时,把发送时间纪录到此字段内。1.1新增字段sendtime_至9packetcommonheader内(修改common/packet.h)structhdr_cmn{enum"dir_t{DOWN=-1,NONE=0,UP=1};packet」ptype_;//packettype(seeabove)intsize_;//simulatedpacketsizeintuid_;//uniqueidinterror_;//errorflaginterrbitcnt_;//#ofcorruptedbitsjahnintfecsize_;doublets_;//timestamp:forq-delaymeasurementintiface_;//receivinginterface(label)dir_tdirection_;//direction:0=none,1=up,-1=downdoublesendtime_;//新增的sendtime_字段inlineint&addr_type(){return(addr_type_);}inlineint&num_forwards(){return(num_forwards_);}inlineint&opt_num_forwards(){return(opt_num_forwards_);}//monarch_endinlinedouble&sendtime(){return(sendtime_);}//addedbysmallko}1.2当udp要传送封包出去时,把现在时间加入到sendtime这个字段。(修改apps/udp.cc)voidUdpAgent::sendmsg(intnbytes,AppData*data,constchar*flags){doublelocal_time=Scheduler::instance().clock();while(n-->0){p=allocpkt();hdr_cmn::access(p)->size()=size_;hdr_rtp*rh=hdr_rtp::access(p);rh->flags()=0;rh->seqno()=++seqno_;hdr_cmn::access(p)->timestamp()=(u_int32_t)(SAMPLERATE*local_time);hdr_cmn::access(p)->sendtime_=local_time;//把现在时间加入到sendtime这个字段//add"beginningoftalkspurt"labels(tcl/ex/test-rcvrtcl)if(flags&&(0==strcmp(flags,"NEW_BURST")))rh->flags()|=RTP_M;p->setdata(data);target_->recv(p);}n=nbytes%size_;if(n>0){p=allocpkt();hdr_cmn::access(p)->size()=n;hdr_rtp*rh=hdr_rtp::access(p);rh->flags()=0;rh->seqno()=++seqno_;hdr_cmn::access(p)->timestamp()=(u_int32_t)(SAMPLERATE*local_time);hdr_cmn::access(p)->sendtime_=local_time;//把现在时间加入到sendtime这个字段//add"beginningoftalkspurt"labels(tcl/ex/test-rcvrtcl)if(flags&&(0==strcmp(flags,"NEW_BURST")))rh->flags()|=RTP_M;p->setdata(data);target_->recv(p);}idle();}2.在tools的目录内,新增mymeasure.h和mymeasure.cc[mymeasure.h内容]#include<tclcl.h>#include<stdio.h>#include"agent.h"#include"config.h"#include"packet.h"#include"ip.h"#include"rtp.h"classmymeasure:publicAgent{public:mymeasure();virtualintcommand(intargc,constchar*const*argv);virtualvoidrecv(Packet*pkt,Handler*);protected:intnlost_;〃移失封包数量intnpkts_;〃接收到的封包数量intexpected_;intbytes_;〃接收到的封包总长度(bytes)intseqno_;〃封包序号doublelast_packet_time_;〃上一次封包接收时间charbuf[100];FILE*pFile;doublenow;doublesum_ipdv_;//jitter总和,可以用来算averagejitterdoublesum_owd_;//onewaydelay总和,可以用来算averageowddoublecurrentowd;〃目前所量测至U的onewaydelaydoublecurrent_ipdv_;〃目前所量测到的jitterdoublemin_owd_;〃最小的onewaydelay值doubleprevious_owd_;〃上一次量测至U的onewaydelay};[mymeasure.cc内容]#ineludevtclcl.h>#include"agent.h"#include"config.h"#include"packet.h"#include"ip.h"#include"rtp.h"#include"mymeasure.h"staticclassmymeasureClass:publicTclClass{public:mymeasureClass():TclClass("Agent/mymeasure"){}TclObject*create(int,constchar*const*){return(newmymeasure());}}class_mymeasure;mymeasure::mymeasure():Agent(PT_NTYPE){bytes_=0;nlost_=0;npkts_=0;expected_=-1;last_packet_time_=0.;seqno_=0;TOC\o"1-5"\h\zsum_ipdv_=0;sum_owd_=0;current_owd_=0;current_ipdv_=0;previous_owd_=0;min_owd_=100000000;bind("nlost_",&nlost_);bind("npkts_",&npkts_);bind("bytes_",&bytes_);bind("lastPktTime_",&last_packet_time_);bind("expected_",&expected_);}voidmymeasure::recv(Packet*pkt,Handler*){hdr_rtp*p=hdr_rtp::access(pkt);seqno=p->seqno();bytes_+=hdr_cmn::access(pkt)->size();++npkts_;now=Scheduler::instance().clock();〃计算OneWayDelaycurrent_owd_=(Scheduler::instance().clock()-hdr_cmn::access(pkt)->sendtime_);〃看看量测到的owd是否是最小值if(current_owd_vmin_owd_)min_owd_=current_owd_;sum_owd_+=current_owd_;//onewaydelay总和,可以用来算averageowdif(previous_owd_!=0){//Jitter:ipdv=|current_owd_-previous_owd_|if(previous_owd_vcurrent_owd_)current_ipdv_=(current_owd_-previous_owd_);elsecurrent_ipdv_=(previous_owd_-current_owd_);sum_ipdv_+=current_ipdv_;//ipdv总和,可以用来算averageipdv(Jitter)}previous_owd_=current_owd_;〃在这里,只把onewaydelay的信息写到档案内■若是有不同的需要,可以参照下面这行程序〃把所需的数据写到档案fprintf(pFile,"%0.1f%0.1f\n",now*1000,current_owd_*1000);〃检查封包是否有移失if(expected_>=0){〃从封包序号的不连续性,就可以得知是否有封包移失intloss=seqno_-expected_;if(loss>0){nlost_+=loss;Tcl::instance().evalf("%slog-loss",name());}}last_packet_time_=Scheduler::instance().clock();expected_=seqno_+1;Packet::free(pkt);}intmymeasure::command(intargc,constchar*const*argv){if(strcmp(argv[1],"clear")==0){expected_=-1;return(TCL_OK);〃设定档名if(strcmp(argv[1],"set_filename")==0){strcpy(buf,argv[2]);pFile=fopen(buf,"w");return(TCL_OK);}〃关闭档案if(strcmp(argv[1],"close_file")==0){fclose(pFile);return(TCL_OK);}return(Agent::command(argc,argv));}修改ns-default.tcl档,把下面的程序代码加入。Agent/mymeasuresetnlost_0Agent/mymeasuresetnpkts_0Agent/mymeasuresetbytes_0Agent/mymeasuresetlastPktTime_0Agent/mymeasuresetexpected_0在Makefile内把tools/mymeasure.o加入OBJ_CC内。重新Make。测试。下面的程序代码是用来测试OneWayDelay的setns[newSimulator]settestTime85.0sets[$nsnode]setd[$nsnode]$nsduplex-link$s$d10Mb5.5msDropTailsetudp[newAgent/UDP]$nsattach-agent$s$udpsetcbr[newApplication/Traffic/CBR]$cbrattach-agent$udp$cbrsetpacket_size_1000$udpsetpacketSize_1000$cbrsetrate_1000000setnull[newAgent/mymeasure]$nsattach-agent$d$null$nsconnect$udp$null$nullset_filenameowd_flow0procfinish{}{globalnsexit0$nsat0.0"$cbrstart"$nsat$testTime"$cbrstop"$nsat$testTime"$nullclose_file"$nsat[expr$testTime+1.0]"finish"$nsrun执行结束后,会产生一个档案owd_flowO,里面纪录了每个封包的one-way-delay。TOC\o"1-5"\h\z6.3由于测试的程序是CBR,所以所有的数据都是6.3ms(包含了5.5ms的propagationdelay和封包被节点处理时间)。Howtomeasurethethroughput,packetdroprate,andend-to-enddelayforUDP-basedapplicationoverwirelessnetworks?[scenario]Itconsistsof8mobilenodes:4sourcenodesand4destinationnode.EachsourceisaCBRsourceoverUDP.Thesizeofatransmittedpacketis512bytes.Transmissionrateofanodeis600Kbps.Weassumedthatthenodesareintransmissionrangeataconstantdistaneeof195m.Thesimulationtimelastedfor80sec.[TCLscript]sourcefromJoeNaoum-Sawaya##DefineNodeConfigurationparamaters#=======================================================setval(chan)Channel/WirelessChannel;#channeltypesetval(prop)Propagation/TwoRayGround;#radio-propagationmodelsetval(netif)Phy/WirelessPhy;#networkinterfacetypesetval(mac)Mac/802_11;#MACtypesetval(ifq)Queue/DropTail/PriQueue;#interfacequeuetypesetval(ll)LL;#linklayertypesetval(ant)Antenna/OmniAntenna;#antennamodelsetval(ifqlen)50;#maxpacketinifqsetval(nn)8;#numberofmobilenodessetval(rp)DSDV;#routingprotocolsetval(x)500;#Xdimensionofthetopographysetval(y)500;#YdimensionofthetopographyMac/802_11setRTSThreshold_3000Mac/802_11setbasicRate_1MbMac/802_11setdataRate_2Mb#=======================================================#Initializetracefiledesctiptors#=======================================================***ThroughputTrace***setf0[openout02.trw]setfl[openout12.trw]setf2[openout22.trw]setf3[openout32.trw]***PacketLossTrace***setf4[openlost02.trw]setf5[openIost12.trw]setf6[openlost22.trw]setf7[openIost32.trw]***PacketDelayTrace***setf8[opendelay02.trw]setf9[opendelay12.trw]setf10[opendelay22.trw]setf11[opendelay32.trw]***InitializeSimulator***setns_[newSimulator]***InitializeTracefile***settracefd[opentrace2.trw]$ns_trace-all$tracefd***InitializeNetworkAnimator***setnamtrace[opensim12.namw]$ns_namtrace-aH-wireless$namtrace$val(x)$val(y)***setuptopographyobject***settopo[newTopography]$topoload_flatgrid500500CreateGeneralOperationsDirector(GOD)object.Itisusedtostoreglobalinformationaboutthestateoftheenvironment,network,ornodesthatanomniscentobserverwouldhave,butthatshouldnotbemadeknowntoanyparticipantinthesimulation.create-god$val(nn)configurenodes$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)\-channeIType$val(chan)\-topoInstanee$topo\-agentTraceON\-routerTraceON\-macTraceOFF\-movementTraceOFFCreateNodesfor{seti0}{$i<$val(nn)}{incri}{setnode($i)[$nsnode]$node_($i)random-motion0;#disablerandommotion}InitializeNodeCoordinates$node_(0)setX_5.0$node_(0)setY_5.0$node_(0)setZ_0.0$node_(1)setX_200.0$node_(1)setY_5.0$node_(1)setZ_0.0$node_(2)setX_5.0$node_(2)setY_50.0$node_(2)setZ_0.0$node_(3)setX_200.0$node_(3)setY_50.0$node_(3)setZ_0.0$node_(4)setX_5.0$node_(4)setY_100.0$node_(4)setZ_0.0$node_(5)setX_200.0$node_(5)setY_100.0$node_(5)setZ_0.0$node_(6)setX_2.0$node_(6)setY_150.0$node_(6)setZ_0.0$node_(7)setX_200.0$node_(7)setY_150.0$node_(7)setZ_0.0SetuptrafficflowbetweennodesTCPconnectionsbetweennode_(0)andnode_(1)CreateConstantfourBitRateTrafficsourcessetagent1[newAgent/UDP];#CreateTCPAgent$agent1setprio_0;#SetItspriorityto0setsink[newAgent/LossMonitor];#CreateLossMonitorSinkinordertobeabletotracethenumberobytesreceived$ns_attach-agent$node_(0)$agent1;#AttachAgenttosourcenode$ns_attach-agent$node_(1)$sink;#AttachAgenttosinknode$nsconnect$agent1$sink;#Connectthenodes
setapp1[newApplication/Traffic/CBR];#CreateConstantBitRateapplication$app1setpacketSize_512$app1setrate_600Kb$app1attach-agent$agent1;#SetPacketSizeto512bytes;#SetCBRrateto200Kbits/sec;#AttachApplicationtoagentsetagent2[newAgent/UDP];#SetPacketSizeto512bytes;#SetCBRrateto200Kbits/sec;#AttachApplicationtoagentsetagent2[newAgent/UDP]$agent2setprio_1setsink2[newAgent/LossMonitor]tracethenumberobytesreceived$ns_attach-agent$node_(2)$agent2$ns_attach-agent$node_(3)$sink2$ns_connect$agent2$sink2;#CreateTCPAgent;#SetItspriorityto1;#CreateLossMonitorSinkinordertobeableto;#AttachAgenttosinknode;#Connectthenodessetapp2[newApplication/Traffic/CBR];#CreateConstantBitRateapplication$app2setpacketSize_512$app2setrate_600Kb$app2setpacketSize_512$app2setrate_600Kb$app2attach-agent$agent2;#SetCBRrateto200Kbits/secsetagent3[newAgent/UDP]$agent3setprio_2setsink3[newAgent/LossMonitor]tracethenumberobytesreceivedsetagent3[newAgent/UDP]$agent3setprio_2setsink3[newAgent/LossMonitor]tracethenumberobytesreceived$ns_attach-agent$node_(4)$agent3$ns_attach-agent$node_(5)$sink3;#CreateTCPAgent;#SetItspriorityto2;#CreateLossMonitorSinkinordertobeableto;#AttachAgenttosourcenode;#AttachAgenttosinknode$ns_connect$agent3$sink3;#Connectthenodes;#SetPacketSizeto512bytes;#SetCBRrateto200Kbits/sec;#SetPacketSizeto512bytes;#SetCBRrateto200Kbits/sec;#AttachApplicationtoagent$app3setrate_600Kb$app3attach-agent$agent3setagent4[newAgent/UDP]$agent4setprio_3setagent4[newAgent/UDP]$agent4setprio_3setsink4[newAgent/LossMonitor]tracethenumberobytesreceived$ns_attach-agent$node_(6)$agent4$ns_attach-agent$node_(7)$sink4$ns_connect$agent4$sink4;#SetItspriorityto3;#CreateLossMonitorSinkinordertobeableto;#AttachAgenttosourcenode;#AttachAgenttosinknode;#Connectthenodessetapp4[newApplication/Traffic/CBR];#CreateConstantBitRateapplication$app4setpacketSize_512;#SetPacketSizeto512bytes$app4setrate_600Kb;#SetCBRrateto200Kbits/sec$app4attach-agent$agent4;#AttachApplicationtoagent#definesthenodesizeinNetworkAnimatorfor{seti0}{$i<$val(nn)}{incri}{$ns_initial_node_pos$node_($i)20}#InitializeFlagssetholdtime0setholdseq0setholdtimel0setholdseql0setholdtime20setholdseq20setholdtime30setholdseq30setholdratel0setholdrate20setholdrate30setholdrate40#FunctionTorecordStatistcis(BitRate,Delay,Drop)procrecord{}{globalsinksink2sink3sink4f0f1f2f3f4f5f6f7holdtimeholdseqholdtime1holdseq1holdtime2holdseq2holdtime3holdseq3f8f9f10f11holdrate1hol
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年社会主义核心价值观知识试题库附答案
- 2025年行政执法资格考试聚题库附答案
- 财务咨询公司制度
- 《百合花》教学课件
- 《高考语文复习:小说反套路题型》课件
- 城市轨道交通消防与环控系统检修电子教案-项目二任务三 通风空调系统运行模式
- 2026 幼儿情绪管理害怕情绪安抚方法课件
- 汉中市辅警招聘笔试题及答案
- 邯郸市辅警招聘考试题及答案
- 2026 四年级上册《植物的蒸腾作用》课件
- 2026年机电维修电工考试试题及答案
- 对外投资合作国别(地区)指南 2025 秘鲁
- 义务教育均衡发展质量监测八年级综合试卷测试题
- 2026年检察院聘用制书记员招聘笔试试题(含答案)
- 2025年护理质控工作总结及2026年工作计划汇报
- 2025年宁夏事业单位招聘考试(面试)细选试题及试题答案解析
- 个人所得税退税课件
- 2025年微生物检验技术真题卷
- 2024年江苏省苏州市中考化学真题(解析版)
- GB/T 46585-2025建筑用绝热制品试件线性尺寸的测量
- 医药信息咨询公司管理制度
评论
0/150
提交评论