N/A
N/A
N/A
N/A
N/A
在許多 ns2 的討論區中,可以看到 AWK 常被用來分析 trace 檔。這是因為 AWK 對於處理由資料列所組成的文字檔特別拿手,因此對於處理 trace 檔可以說是一項重要的工具。
AWK 的特性
AWK 的特性如下:
直譯器
變數無型態之分
可用文字當陣列的索引
善於處理據資料列與欄位型態的資料
在這裡我們不打算詳細地介紹 AWK,因為已經有許多文獻,如中研院的AWK Tutorial Guide。因此,閱讀完此份文件你應該已經能夠撰寫處理 ns2 trace 檔的 AWK 程式。接下來,就讓我們來看看要怎麼寫一個 AWK 程式來處理 trace 檔吧!
AWK 的內建變數
當你在撰寫處理 trace 檔的 AWK 程式時,你可能會需要用到下列內建變數。
AWK 的內建函式
AWK 的內建函式相當多,並且與C語言的用法大致相同。因此,我們只介紹一些簡單的數學函式並陸續補充在並陸續補充分析 ns2 trace 檔所需要的函式,若是你需要使用到其它的函式可以參考中研院的AWK Tutorial Guide。
AWK 程式的架構
一個 AWK 程式主要可以區分為三大部分。
1.程式初始化部分
BEGIN {
# 初始化程式(執行一次)
}
這個部分的程式碼只會在程式開始時被執行一次,因此通常被用來定義一些為了計算網路效能值的全域變數。例如,符合某些條件的封包數(總封包數,被丟棄封包數)或是暫時用到的變數(第 n 秒收到的封包)...等等。
2.重複執行的部分
Pattern-1 {Action-1} # 符合 Pattern-1 的資料列都會執行 Action-1
Pattern-2 {Action-2} # 符合 Pattern-2 的資料列都會執行 Action-2
... # 以此類推 (如果沒有指定 Pattern,則表示無條件執行 Action。)
在執行完 AWK 程式的第一部分後,下面四個步驟會反複執行直到所有資料列被處理完為止。
Step 1: 自動從資料檔中讀取下一筆資料列。
Step 2: 自動更新相關的內建變數之值。 如,NF,NR,$0,...等。
Step 3: 逐次執行程式中所有的 Pattern {Actions} 指令。
Step 4: 當執行完程式中所有 Pattern {Actions} 後,如果資料檔中還有未讀取的資料列,則回到 Step 1 繼續執行。
3.程式結束部分
END {
# 結束程式(執行一次)
}
這個部分的程式碼只會在程式結束時被執行一次,因此通常被用來計算需要看完全部資料列才能夠計算的數值。
接下來,我們就來介紹什麼是 Pattern、Action、以及一些會用到的小技巧。
Pattern的用法
Pattern 主要是描述是否執行 Action 的條件,主要的條件可以分成下面兩種:
關係式 (Relational expression)
正則式 (Regular expression)
Action的用法
Actions 是由許多應用到資料列上的 AWK 指令所構成。而 AWK 的指令與 C 語言中的指令十分類似。例如:
AWK 的 I/O 指令
printf( )
getline
...
AWK 的流程控制指令
if(...){..} else{..}
while(...){...}
...
...
陣列的用法
在 AWK 中使用陣列相當具有彈性,其特性如下:
可以使用字串當作索引
不需要事先宣告大小
而陣列的索引方式可以分成下列兩種:
以數字當索引
使用方法與C++相同
以字串當索引
範例如下
BEGIN {
}
{
if ($0 ~ "O.S.") A["O.S"]++;
if ($0 ~ "D.S.") A["D.S"]++;
if ($0 ~ "Discrete") A["Discrete"]++;
if ($0 ~ "Graphics") A["Graphics"]++;
if ($0 ~ "Arch.") A["Arch."]++;
if ($0 ~ "A.I.") A["A.I."]++;
if ($0 ~ "Algorithm") A["Algorithm"]++;
}
END {
for (course in A)
print course, A[course];
}
案例學習
在有了基礎的 AWK 程式設計概念之後,要如何利用 AWK 程式來處理 ns2 的 trace 檔案以便產生可以畫出網路效能曲線圖形的檔案。你可以根據下面的步驟來完成所需要的 AWK 程式並繪製圖形:
Step 1: 定義你的網路效能評估值。
Step 2: 根據網路效能評估值的定義撰寫 AWK 程式。
Step 3: 執行你的 AWK 程式來處理 ns2 的 trace 檔案。
Step 4: 繪製你要的圖表。
接下來,我們用一個簡單的範例來說明上面的流程。假設我們想要得到每 0.1 秒被丟棄(drop)之總封包數的曲線圖,該怎麼作呢?
Step 1: 定義你的網路效能評估值。
每 0.1 秒被丟棄之總封包數的定義
每隔 0.1 秒在所有節點被丟掉的封包數總合
在 trace 檔中需要用到的欄位
事件類別 ($1)
事件發生的時間 ($2)
判斷式
計算 $2 在 t ~ (t+1) 秒中 $1 為 d 的數目
Step 2: 根據網路效能評估值的定義撰寫 AWK 程式。
BEGIN {
# 全域變數
drop_count = 0; # 被丟棄的封包數
current_sec = 0; # 目前的秒數
}
{
# 利用可記憶的變數來取代欄位符號可以讓程式更容易閱讀
event_class = $1;
event_time = $2;
link_src = $3;
link_dst = $4;
pkt_class = $5;
pkt_size = $6;
pkt_flag = $7;
flow_id = $8;
flow_src = $9;
flow_dst = $10;
seq_no = $11;
pkt_id = $12;
# ##################### #
# 撰寫程式說明是一個好習慣 #
# ##################### #
if(event_time >= current_sec && event_time < current_sec + 0.1) {
if(event_class == "d"){
drop_count++;
}
}
if(event_time >= current_sec + 0.1) {
print current_sec + 0.1, drop_count;
current_sec = current_sec + 0.1;
drop_count = 0;
if(event_class == "d") {
drop_count++;
}
}
}
END {
}
Step 3: 執行你的 AWK 程式來處理 ns2 的 trace 檔案。
awk –f program_filename trace_filename > output_filename
Step 4: 繪製你要的圖表。
請參考本份文件的圖形繪製一節。
N/A
N/A
我們做完網路模擬後所產生出來的曲線檔案主要是讓我們能夠畫出 2D 曲線圖,以便觀察網路效能。因此,這個用來繪圖的曲線檔案其格式是由兩個欄位的資料列所組成的。其中第一欄是 X 軸的值,而第二個欄位則是 Y 軸的值。
事實上,可以利用這個曲線檔案來繪圖的工具包含了 XGRAPH、GNUPLOT、或是 MATLAB。但是,因為 XGRAPH 所繪製出來的圖形較不適合放在文章上,所以大部分的人都選用後兩者來產生需要的圖形。
N/A
N/A
如何讀入取線檔案
MATLAB 是一套強大的數值分析工具,然而卻沒有辦法直接讀入曲線檔案。然而,這對善於處理矩陣的 MATLAB 來說並不是一個很大的問題。下面這一個 m 檔案,可以讀入一個曲線檔案並回傳一個二維陣列,其中第一列是所有 X 軸的值,而第二列是所有 Y 軸的值:
function MyData = WTReadPlotFile(filename)
% %%%%%%%%%%%%%%%%%%
% Program name: WTReadPlotFile.m
% Author: Wei-Tsung Su
% %%%%%%%%%%%%%%%%%%
fid = fopen(filename,'r');
MyData = fscanf(fid,'%g %g', [2, inf]);
fclose(fid);
接下來,你就可以利用 MATLAB 讀入取線檔案來產生圖形。
如何利用 WTReadPlotFile.m 來產生圖形
假設,你有兩個曲線檔案(1.result 以及 2.result)要畫在一同一張圖上,那麼下面這段 MATLAB 程式可以畫出所需要的圖形:
% Get Your Plot Data from Files %
plot1 = WTReadPlotFile('1.result');
plot2 = WTReadPlotFile('2.result');
% Plot Your Curves in one figure
plot(plot1(1,:),plot1(2,:),'-o',plot2(1,:),plot2(2,:),'-x');
% Define Labels
xlabel('Simulation Time (s)');
ylabel('Total Dropped Packet (Pkt)');
title('Total Dropped Packet');
legend('Method A','Method B');
那麼你就可以將兩個方法的曲線擺在一起比較。(關於詳細的 MATLAB 繪圖技巧,請參會相關資料。)
如何指定產生圖檔的 DPI 值
下面這個 MATLAB 指令可以將目前在 MATLAB 所產生出來的圖形轉成你想要的格式:
print -d(檔案格式[bmp | eps | tiff | ...]) -r(dpi值)
N/A
N/A
N/A
Trace檔的內容
在完成模擬之後,ns2 會產生一個副檔名為 .tr 的 trace 檔案,該檔案詳細紀錄了封包在網路上傳送的過程。這個檔案可以提供給使用者作為事後分析(post analysis)用途之用。ns2 的有線網路 trace 檔是一個由 12 個欄位組成的資料列集合並依照 事件發生的時間 (第二個欄位) 排序。下面是一個有線網路的 trace 檔範例。
1 2 3 4 5 6 7 8 9 10 11 12
r 1.995918 0 2 cbr 210 ------- 0 0.0 3.1 265 623
+ 1.995918 2 3 cbr 210 ------- 0 0.0 3.1 265 623
d 1.995918 2 3 cbr 210 ------- 0 0.0 3.1 265 623
r 1.996120 3 2 cbr 210 ------- 1 3.0 1.0 236 616
+ 1.996120 2 1 cbr 210 ------- 1 3.0 1.0 236 616
- 1.996120 2 1 cbr 210 ------- 1 3.0 1.0 236 616
下面是各個欄位的意義,
具備上述概念並搭配 AWK 程式,你就可以根據所需求撰寫 AWK 程式來觀測網路效能。
N/A
無線網路是目前相當熱門的研究主題,因此 ns2 當然不可能少了無線網路(主要是無線區域網路)的模擬。本節將利用一個簡單的範例來說明模擬無線網路的步驟。
由於 ns2 也可以模擬包含了具有移動性質的 Ad Hoc 網路,因此一開始為了簡化說明,我們先假設節點不會移動然後再說明如何將移動的特性加入模擬中。
TCL 程式碼結構(假設節點不會移動)
我們用一個無線模擬 TCL 模版程式來介紹一個無線網路模擬的 TCL 程式碼可以被區分為如下幾個部分(你可以在最下方的檔案分享一節中下載這一個模版程式):
1.實驗參數設定區
# ================ #
# 1.實驗參數設定區 #
# ================ #
# ============ #
# 1.A.節點參數 #
# ============ #
set val(rp) AODV ;# routing protocol (路由協定)
set val(ll) LL ;# link layer type
set val(mac) Mac/802_11 ;# MAC type (MAC協定)
set val(ifq) Queue/DropTail/PriQueue ;# interface queue type
set val(ifqlen) 50 ;# max packet in ifq
set val(ant) Antenna/OmniAntenna ;# antenna model (天線模型)
set val(prop) Propagation/TwoRayGround ;# radio-propagation model
set val(netif) Phy/WirelessPhy ;# network interface type
set val(chan) Channel/WirelessChannel ;# channel type
set val(engmodel) EnergyModel ;# energy model
set val(initeng) 100.0 ;# initial energy in Joules
set val(txPower) 0.660 ;
set val(rxPower) 0.395 ;
set val(idlePower) 0.035 ;
set val(AgentTrace) OFF ;
set val(RouterTrace) OFF ;
set val(MacTrace) ON ;
set val(MovementTrace) OFF ;
# ============ #
# 1.B.模擬參數 #
# ============ #
set val(x) 100 ;# X dimension of topology (拓樸範圍:X軸)
set val(y) 100 ;# Y dimension of topology (拓樸範圍:Y軸)
set val(nn) 3 ;# number of mobilenodes (節點個數)
set val(seed) 0.0 ;
set val(stop) 10.0 ;# simulation time (模擬時間)
set val(tr) mytrace.tr ;# trace file name (trace檔名)
set val(namtr) mynamtrace.tr ;# nam trace file name (nam trace檔名)
set val(sc) "" ;# node movement model file (移動情境檔)
set val(cp) "" ;# traffic model file (訊流情境檔)
# ============================== #
# 1.C.元件參數設定(如果需要的話) #
# ============================== #
Antenna/OmniAntenna set X_ 0
Antenna/OmniAntenna set Y_ 0
Antenna/OmniAntenna set Z_ 1.5
Antenna/OmniAntenna set Gt_ 1.0
Antenna/OmniAntenna set Gr_ 1.0
2.ns2 模擬器變數設定區
# ======================================= #
# 2.ns2 模擬器變數設定區 (非必要不需變動) #
# ======================================= #
# Initialize Global Variables
set ns_ [new Simulator]
# Open trace file
$ns_ use-newtrace ;# Use new trace format
set namfd [open $val(namtr) w]
$ns_ namtrace-all-wireless $namfd $val(x) $val(y)
set tracefd [open $val(tr) w]
$ns_ trace-all $tracefd
# set up topography object
set topo [new Topography] ;# 紀錄 MobileNodes 在拓樸內移動的情況
$topo load_flatgrid $val(x) $val(y) ;# 給定拓樸的範圍
# create channel
set chan [new $val(chan)]
# Create God
set god_ [create-god $val(nn)]
3.節點產生區
# ============ #
# 3.節點產生區 #
# ============ #
# Create the specified number of mobile nodes [$val(nn)] and "attach" them to the channel.
# =========================== #
# 3.A.設定 Mobile node 的參數 #
# =========================== #
$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) \
-channel $chan \
-topoInstance $topo \
-energyModel $val(engmodel) \
-initialEnergy $val(initeng) \
-rxPower $val(rxPower) \
-txPower $val(txPower) \
-idlePower $val(idlePower) \
-agentTrace $val(AgentTrace) \
-routerTrace $val(RouterTrace) \
-macTrace $val(MacTrace) \
-movementTrace $val(MovementTrace)
# ============ #
# 3.B.產生節點 #
# ============ #
for {set i 0} {$i < $val(nn) } {incr i} {
set node_($i) [$ns_ node]
$node_($i) random-motion 0 ;# disable random motion
$god_ new_node $node_($i) ;# if you want to use IsNeighbor, the mem func of God, just do so
}
# ========================== #
# 3.C.給定初始位置與移動情境 #
# ========================== #
$node_(0) set X_ 0
$node_(0) set Y_ 0
$node_(0) set Z_ 0
$ns_ initial_node_pos $node_(0) $val(nn)
$node_(1) set X_ 50
$node_(1) set Y_ 50
$node_(1) set Z_ 0
$ns_ initial_node_pos $node_(1) $val(nn)
$node_(2) set X_ 100
$node_(2) set Y_ 100
$node_(2) set Z_ 0
$ns_ initial_node_pos $node_(2) $val(nn)
4.訊流定義區
# ============ #
# 4.訊流定義區 #
# ============ #
# Flow 0: node(0) <- FTP/TCP -> node(2)
set tcp(0) [new Agent/TCP]
set sink(0) [new Agent/TCPSink]
$ns_ attach-agent $node_(0) $tcp(0)
$ns_ attach-agent $node_(2) $sink(0)
$ns_ connect $tcp(0) $sink(0)
$tcp(0) set fid_ 0
$tcp(0) set window_ 128
$tcp(0) set packetSize_ 512
set ftp(0) [new Application/FTP]
$ftp(0) attach-agent $tcp(0)
$ftp(0) set type_ FTP
$ns_ at 0.2 "$ftp(0) start"
# 以此類推
5.模擬時間設定區
此主要是設定模擬開始與結束時間。
# ================ #
# 5.模擬時間設定區 #
# ================ #
# Tell nodes when the simulation ends
# 設定節點模擬結束時間
for {set i 0} {$i < $val(nn) } {incr i} {
$ns_ at $val(stop) "$node_($i) reset";
}
$ns_ at $val(stop) "stop"
$ns_ at $val(stop) "puts \"NS EXITING...\"
$ns_ halt"
6.輔助函式定義區
此區可以定義一些在 TCL 程式中可能常會用到或是可以模組化的函式。
# ================ #
# 6.輔助函式定義區 #
# ================ #
proc stop {} {
global ns_ tracefd namfd
$ns_ flush-trace
close $tracefd
close $namfd
}
7.程式起始命令
# ============== #
# 7.程式起始命令 #
# ============== #
puts "Starting Simulation..."
$ns_ run
上 面的範例的情境是 3 個不會移動的節點隨機分布在 100x100 的範圍中,而節點 0 和節點 2 之間有 FTP 訊流。其中,網路拓僕的建立是透過 AODV 路由協定所建構而成。那麼,如果要模擬一個真正的 Ad Hoc 網路(也就是節點會移動的情形)又該怎麼作呢?
加入移動情境
在 ns2 中有兩種模擬移動節點的模型 (model),隨機移動模型 與 Random-Way Point 移動模型。我們將針對兩種模型來對上面的範例作修正。
隨機移動模型
在隨機移動模型,節點會從一個隨機位置開始並不斷的改變方向和速度(事實上,改變的幅度似乎不大)。你只需要執行一個步驟就可以完成隨機移動模型的模擬。
在產生節點的迴圈(3.B)中,將原本的 TCL 程式碼改成如下:
for {set i 0} {$i < $val(nn) } {incr i} {
set node_($i) [$ns_ node]
$node_($i) random-motion 1 ;# enable random motion
$node_($i) start
$god_ new_node $node_($i) ;# if you want to use IsNeighbor, the mem func of God, just do so
}
Random-Way Point 移動模型
還記得在上面的範例中,你必須透過下面的指令來設定節點的初始位置
$node set X_ <x1>
$node set Y_ <y1>
$node set Z_ <z1>
事實上,你還可以透過下面的指令來設定節點未來的位置(然而,這個指令再編寫此份文件的時候還沒有支援 y 軸的移動。)
# 節點 $node 在第 $time 秒以 $speed 速度移動到 <x2> <y2> 位置
$ns at $time $node setdest <x2> <y2> <speed>
事實上,透過上面這個指令,你可以隨心所欲的設定任何節點在任何時間應該移動到哪一個位置。然而,在 CMU 很貼心的寫了一個小程式讓你可以自動產生符合 Random-Way Point 移動模型並且是以上述指令所組成的移動情境檔案。你可以編譯在
~ns/indep-utils/cmu-scen-gen/setdest/
目錄下的程式碼以產生移動情境產生器(setdest)。你可以透過下面的指令來自動產生你所需要的移動情境:
./setdest -v 1 -n <num_of_nodes> -p <pausetime> -M <maxspeed> -t <simtime> -x <maxx> -y <maxy> > <outdir>/<scenario-file>
或是
./setdest -v 2 -n <num_of_nodes> -P <pausetype> -p <pausetime> -s <speedtype> -m <minspeed> -M <maxspeed> -t <simtime> -x <maxx> -y <maxy> > <outdir>/<scenario-file>
其中,第 2 版比第 1 版多了下列 3 個選項:
接著,只要簡單的兩個步驟就可以將移動情境加入模擬中,
第 1 步是在 TCL 程式中設定模擬器參數(1.B)時,將下列參數
set val(sc) "" ;# node movement model file
改成
set val(sc) "<outdir>/<scenario-file>" ;# node movement model file
第 2 步是在 TCL 程式中設定節點初始位置以及移動情境時,加入
source $val(sc)
那麼你就不需要另外撰寫 TCL 程式碼來設定每個節點的初始位置和移動情境。這樣是不是相當方便呢!
自動產生訊流
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
attachment:無線模擬TCL模版程式