1. 程式人生 > >NS2 trace檔案分析指令碼(適合無線trace)

NS2 trace檔案分析指令碼(適合無線trace)

絡上有不少awk程式是講如何分析網路效能的(主要是時延,吞吐量,丟包率和時延抖動),但是都沒有詳細的說明,我在此作一些示例,添加了一些必要的說明註釋。

以下的內容是針對NS2模擬的結果trace檔案進行網路效能分析,看本篇前需要先行了解的的內容有:awk語言的基礎,包括語法和結構等;在Linux下如何使用xgraphgnuplot

因為只是想簡單介紹如何用gwakxgraph/gnuplot處理trace檔案得出分析結果,所以並沒有寫專門的tcl指令碼,分析用的tcl指令碼和trace檔案是一個三節點的無線網路的例子,隨篇附後。

本篇主要想介紹如何得到網路的資料傳輸延遲(delay)、丟包率(

drop)、延時抖動(Jitter)和網路的吞吐量(throughtput),下文的四個awk程式所使用的模型主要來自《網路模擬軟體NS2來做網路效能分析需看的文章》一文,除了第四個外程式沒有做很大的改動,只是對封包的處理有所不同,同時第一個程式增加了比較詳細的註釋,方便初學者學習。因為只是想拋磚引玉,所以分析用的數學模型沒有刻意去研究,有待大家一起討論。

一,延時分析。包的延時就是指包的接收時間與包的傳送時間差。下面給出awk程式,相關的說明看程式裡面的註釋。

#BEGIN表明這是程式開頭執行的一段語句,且只執行一次。

BEGIN {

#程式初始化,設定一變數以記錄目前處理的封包的最大

ID號碼。在awk環境下變數的使用不需要宣告,直接賦值。

highest_uid = 0;

}

#下面大括號裡面的內容會針對要進行處理的記錄(也就是我們的trace檔案)的每一行都重複執行一次

{

event = $1; #$1表示一行的第一欄,是事件的動作。每一欄預設是以空格分隔的。下同。

time = $2; #事件發生的時間

node_nb = $3; #發生事件的節點號(但是兩邊夾著“_”,下面一句程式碼將“_”處理掉)

node_nb=substr(node_nb,2,1); #第三欄的內容是形如_0_的節點號碼,我只要得出中間的節點號碼0,所以要對字串_0_進行處理。

trace_type = $4; #trace

檔案跟蹤事件的層次(指在路由層或mac層等等)

flag = $5; #

uid = $6; #包的uid號碼(普通包頭的uid

pkt_type = $7; #包的型別(是信令或是資料)

pkt_size = $8; #包的大小(byte

#下面的程式碼記錄目前最高的CBR流的packet ID,本來的延遲分析是針對所有的包的(包括信令),這裡作了簡化,只針對CBR封包,以後大家做延時分析可以做相應的改動即可。

if ( event=="s" && node_nb==0 && pkt_type=="cbr" && uid > highest_uid )

{#if判斷句的前三個判斷條件就不說了,第四個是說每個包的記錄次數不超過1

highest_uid = uid;

}

#記錄封包的傳送時間

if ( event=="s" && node_nb==0 && pkt_type=="cbr" && uid==highest_uid )

start_time[uid] = time; # start_time[]表明這是一個數組

#記錄封包的接收時間

if ( event=="r" && node_nb ==2 && pkt_type=="cbr" && uid==highest_uid )

end_time[uid] = time;

}

#END表明這是程式結束前執行的語句,也只執行一次

END {

#當每行資料都讀取完畢後,開始計算有效封包的端到端延遲時間。

for ( packet_id = 0; packet_id <= highest_uid; packet_id++ )

{

start = start_time[packet_id];

end = end_time[packet_id];

packet_duration = end - start;

#只把接收時間大於傳送時間的記錄打印出來

if ( start < end ) printf("%d %f\n", packet_id, packet_duration);

}

}

要注意的是上面的awk程式只是在一個層上進行處理的(我是用的mac層),在生成trace檔案時把其他層關閉,只留一個層,否則判斷條件要多加一個層的判斷。下面的其他三個程式也是一樣的。

程式寫好以後用一個文件儲存為pkt_delaytrace檔案放於同一資料夾下,然後在終端進入該資料夾,執行:

$gwak –f delay trace > p

然後在檔案p中就儲存了兩列資料:封包的序號和該封包的傳送時間。

二,丟包率分析。

BEGIN {

#程式初始化,設定變數記錄傳輸以及被丟棄的包的數目

fsDrops = 0; #被丟棄的包的數目

numfs0 = 0; #0節點發送的CBR封包的數目

numfs2 = 0; #2節點接收的CBR封包的數目

}

{

event = $1;

time = $2;

node_nb = $3;

trace_type = $4;

flag = $5;

uid = $6

pkt_type = $7;

pkt_size = $8;

node_nb=substr(node_nb,2,1);

#統計節點0傳送的CBR封包

if (node_nb==0 && event== "s" && trace_type== "MAC" && pkt_type== "cbr")

numfs0++;

#統計節點2丟棄的CBR封包

if (node_nb==2 && event== "r" && trace_type== "MAC" && pkt_type== "cbr")

numfs2++;

}

END {

average=0; #average用於記錄丟包率

fsDrops = numfs0-numfs2; #丟包數目

average=fsDrops/numfs0; #丟包率

printf("number of packets sent:%d lost_rate:%d\n", numfs0, average); #打印發送封包數目和丟包率

}

程式寫好以後用一個文件儲存為droptrace檔案放於同一資料夾下,然後在終端進入該資料夾,執行:

$gwak –f drop trace > d

檔案d中記錄了兩個資料:傳送封包數目和丟包率。

三,延時抖動分析

在這裡特別提一下,所用的延時抖動分析的模型是:(封包n2的延時-封包n1的延時)/n2的包序號-n1的包序號)。

BEGIN {

#程式初始化,設定一變數以記錄目前處理過的最高封包序號。

highest_uid = 0;

}

{

event = $1;

time = $2;

node_nb = $3;

node_nb=substr(node_nb,2,1);

trace_type = $4;

flag = $5;

uid = $6

pkt_type = $7;

pkt_size = $8;

#記錄目前最高的CBR封包的ID

if ( event=="s" && node_nb==0 && pkt_type=="cbr" && uid > highest_uid )

{

highest_uid = uid;

}

#記錄CBR封包的傳送時間

if ( event=="s" && node_nb==0 && pkt_type=="cbr" && uid==highest_uid )

start_time[uid] = time;

#記錄CBR封包的接收時間

if ( event=="r" && node_nb ==2 && pkt_type=="cbr" && uid==highest_uid )

end_time[uid] = time;

}

END {

# 初始化抖動延時所需的變數

last_seqno = 0;

last_delay = 0;

seqno_diff = 0;

#當資料行全部讀取後,開始計算有效封包的端到端延遲時間

for ( packet_id = 0; packet_id <= highest_uid; packet_id++ )

{

start = start_time[packet_id];

end = end_time[packet_id];

packet_duration =end - start;

#只把接收時間大於傳送時間的記錄列出來

if ( start < end )

{

# 得到了delay(packet_duration)後計算jitter

seqno_diff = packet_id - last_seqno;

delay_diff = packet_duration - last_delay;

if (seqno_diff == 0)

{

jitter =0;

}

else

{

jitter = delay_diff/seqno_diff;

}

#將有效封包序號以及延時抖動打印出來

printf("%d %f\n", packet_id, jitter);

last_seqno = packet_id;

last_delay = packet_duration;

}

}

}

程式寫好以後用一個文件儲存為jittertrace檔案放於同一資料夾下,然後在終端進入該資料夾,執行:

$gwak –f jitter trace > j

檔案j中記錄了有效封包序號以及延時抖動的情況。

四,網路吞吐量分析

網路的吞吐量是網路效能的一個重要引數,是指在不丟包的情況下單位時間內通過的資料包數量,單位是位元組每秒或位元每秒計算其吞吐量是一件複雜的事情,這裡的模型是從第一個包傳送後,每個包都疊加累算。可能模型不夠精準,只是大概的反映,目的只是想讓大家瞭解如何寫awk的網路吞吐量分析程式。大家切勿借用本模型在要發表的論文上做分析。

BEGIN {

init=0;

i=0;

}

{

event = $1;

time = $2;

node_nb = $3;

node_nb=substr(node_nb,2,1);

trace_type = $4;

flag = $5;

uid = $6

pkt_type = $7;

pkt_size = $8;

if(event=="r" && node_nb==2 && pkt_type=="cbr" )

{

pkt_byte_sum[i+1]=pkt_byte_sum[ i ]+ pkt_size;  //計算一個累計量

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);

}

程式寫好以後用一個文件儲存為throughtputtrace檔案放於同一資料夾下,然後在終端進入該資料夾,執行:

$gwak –f throughtput trace > t

檔案t中記錄了包的接收時間以及吞吐量的情況。

接下來,就是對已經分析得到的結果用圖描繪出來。可以用xgraph或者gnuplot。這種繪圖工具可以將兩列資料中的第一列作橫軸,第二列作縱軸用曲線描繪出來。若把資料檔名儲存為file,則用xgraph繪圖的指令是$xgraph file;用gnuplot繪圖的指令是$gnuplot,進入gnuplot環境後,可以設定標題,橫軸和縱軸的label等:

>set title “titlename”

>set xlabel “xlabelname”

>set ylabel “ylabelname”

然後繪圖:

>plot “file” with lines(用連線方式,gnuplot有九種繪圖方式)

下面用gnuplot描繪延時,延時抖動以及吞吐量的圖形:

1包的延時:

>set title “pkt_delay-pkt_id”

>set xlabel “packet_id”

>set ylabel “packet_delay”

>plot “p” with lines

2延時抖動:

>set title “jitter-packet”

>set xlabel “packet_id”

>set ylabel “jitter”

>plot “j” with lines

3吞吐量:

>set title “throughtput-time”

>set xlabel “time”

>set ylabel “throughtput”

>plot “t” with lines

最後需要說明的是:直接拷貝貼上word文件內的awk程式編譯時一般是通不過的,裡面有很多空格鍵需要去掉,相關的格式對齊用Tab鍵,否則這些格式問題在Linux下會像小蟲一樣令你頭痛不已。