網路效能量測 實驗目的 1. 學習如何量測以 UDP 為傳輸協定的應用程式之吞吐量 (throughput) 封包延遲 (packet dealy) 抖動率(packet jitter) 和封包遺失率(packet loss rate) 2. 學習如何量測以 TCP 為的應用程式之吞吐量 (throughput) 背景知識當模擬結束後, 我們通常會需要使用模擬過程中所產生的模擬過程記錄檔來分析以得到吞吐量 封包延遲 抖動率 或封包遺失率 但是,NS2 所提供的模擬過程記錄檔格式並不是統一的, 模擬環境若是全部都是有線的, 其紀錄檔格式如下所示 : event time from to pkt pkt flags fid src dst seq pkt node node type size addr addr num id r:receive (at to_node) +:enqueue (at queue) -:dequeue (at queue) src_addr:node.port d:drop (at queue) dst_addr:node.port 圖?. 有線網路環境下的模擬過程記錄檔格示 + 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 圖?. 有線網路環境下的模擬過程記錄檔範例
格式說明 : 1. 每一筆記錄的開始都是封包事件發生的原因, 若是 "r" 則表示封包被某個節點所接收 ; 若是 "+" 則表示進入了佇列 ; 若是 "- 則表示離開佇列 ; 若是 "d" 則表示封包被佇列所丟棄 2. 第二個欄位表示的是事件發生的時間 3. 欄位三和欄位四表示事件發生的地點 ( 從 from node 到 to node) 4. 欄位五表示封包的型態 5. 欄位六是封包的大小 6. 欄位七是封包的旗標標註 7. 欄位八表示封包是屬於哪一個資料流 8. 欄位九和欄位十是表示封包的來源端和目的端, 這兩個欄位的格式是 a.b,a 代表節點編號,b 表示埠號 (port number) 9. 欄位十一表示封包的序號 ; 欄位十二表示封包的 id 以前面模擬過程記錄檔的第一筆為例, 意思就是說有一個封包 pakcet id 為 0, 資料流 id 為 2, 序號為 0, 長度為 1000 bytes, 型態為 CBR, 它是從來源端 1.0 要到目的地 3.1, 在時間 0.1 秒的時候, 從節點 1 進入了節點 2 的佇列中 若是模擬環境為無線的, 則模擬過程記錄檔格式則會跟路由協定和是否有設定要使用新格式而不同, 以 DSDV 且沒有設定使用新格式的範例如下所示 : s 0.029290548 _1_ RTR --- 0 message 32 [0 0 0 0] ------- [1:255-1:255 32 0] s 0.029365548 _1_ MAC --- 0 message 84 [0 ffffffff 1 800] ------- [1:255-1:255 32 0] r 0.030037615 _0_ MAC --- 0 message 32 [0 ffffffff 1 800] ------- [1:255-1:255 32 0] r 0.030062615 _0_ RTR --- 0 message 32 [0 ffffffff 1 800] ------- [1:255-1:255 32 0] s 1.000000000 _0_ AGT --- 1 tcp 40 [0 0 0 0] ------- [0:0 1:0 32 0] [0 0] 0 0 圖? DSDV 且沒有設定使用新格式的範例
格式說明 : 1. 第一個欄位是封包事件發生的原因 s: 傳送 (send) r: 接收 (Receive) d: 丟棄 (Drop) f: 轉送 (Forward) 2. 第二個欄位是事件發生的時間 3. 第三個欄位是事件發生的節點 ID 4. 第四個欄位是說明這是發生在那一層的事件 RTR: 路由層 (Router Trace) AGT: 應用層 (Agent Trace) MAC: 媒體存取層 (Mac Trace) 5. 第七個欄位是封包的型態 6. 第八個欄位是封包的大小 7. 第十四個欄位是來源節點位址 (NodeID:PortNumber) 8. 第十五個欄位是目的節點位址 (NodeID:PortNumber) 其他欄位說明請參考 [1] 若是使用相同的模擬 tcl 檔, 但加入了如 $ns_ use-newtrace ( 使用新的格式 ), 則產生的範例如下所示 : s -t 0.029290548 -Hs 1 -Hd -1 -Ni 1 -Nx 10.00 -Ny 40.00 -Nz 0.00 -Ne -1.000000 -Nl RTR -Nw --- -Ma 0 -Md 0 -Ms 0 -Mt 0 -Is 1.255 -Id -1.255 -It message -Il 32 -If 0 -Ii 0 -Iv 32 s -t 0.029365548 -Hs 1 -Hd -1 -Ni 1 -Nx 10.00 -Ny 40.00 -Nz 0.00 -Ne -1.000000 -Nl MAC -Nw --- -Ma 0 -Md ffffffff -Ms 1 -Mt 800 -Is 1.255 -Id -1.255 -It message -Il 84 -If 0 -Ii 0 -Iv 32 r -t 0.030037615 -Hs 0 -Hd -1 -Ni 0 -Nx 10.00 -Ny 20.00 -Nz 0.00 -Ne -1.000000 -Nl MAC -Nw --- -Ma 0 -Md ffffffff -Ms 1 -Mt 800 -Is 1.255 -Id -1.255 -It message -Il 32 -If 0 -Ii 0 -Iv 32 r -t 0.030062615 -Hs 0 -Hd -1 -Ni 0 -Nx 10.00 -Ny 20.00 -Nz 0.00 -Ne -1.000000 -Nl RTR -Nw --- -Ma 0 -Md ffffffff -Ms 1 -Mt 800 -Is 1.255 -Id -1.255 -It message -Il 32 -If 0 -Ii 0 -Iv 32 圖? DSDV 且設定使用新格式的範例格式說明 : 1. 第一個欄位是封包事件發生的原因 s: 傳送 (send) r: 接收 (Receive) d: 丟棄 (Drop) f: 轉送 (Forward)
2. 第二個欄位是事件發生的時間 -t time ( 時間 ) 3. 第三個欄位是下一站的資訊 (Next hop info) -Hs: id for this node -Hd: id the next hop towards the destination 4. 第四個欄位是節點屬性類型標籤 (Node property type tag) -Ni: node id -Nx Ny -Nz: node's x/y/z coordinate -Ne: node energy level -Nl: trace level, such as AGT, RTR, MAC -Nw: reason for the event 5. 第五個欄位是封包在 IP 層的資訊 (Packet information at IP level) -Is: source address. Source port number ( 來源位置,a.b 其中 a 為節點 ID,b 為埠號 ) -Id: dest address.dest port number ( 目的位置 ) -It: packet type ( 封包類型 ) -Il: packet size ( 封包大小 ) -If: flow id ( 資料流 ID) -Ii: unique id ( 唯一的 ID 編號 ) -Iv: ttl value (Time To Live 的值 ) 6. 第六個欄位是 MAC 層的資訊 (packet info at MAC level) -Ma: duration -Md: destination's ethernet address -Ms: source's ethernet address -Mt: ethernet type 其他欄位說明請參考 [1] 看完以上的簡介後, 讀者就會發現若是直接去分析 NS2 在模擬過程所產生的記錄檔是一件辛苦的事情, 當使用不同的路由協定或者模擬的環境不同時, 所需要的分析程式就會不同, 因而造成使用者的不便 所以筆者就開發了新的記錄檔的方式, 讓使用者能方便的分析模擬的結果 筆者所採用的方法是當有一條以
UDP 為傳輸協定的應用程式開始發送資料時, 當封包從應用程式層到 UDP 層時, 我們就把封包的序號 時間 和大小紀錄到一個檔案中 ( 發送端記錄檔 ), 而當封包到達接收端時, 同樣的我們把收到的封包序號 傳送時間 ( 在傳送端要發送封包時會把當時的時間放在封包的標頭檔 (common header) 中 ) 到達時間 封包延遲時間 (= 到達時間 - 傳送時間 ) 和封包大小紀錄到一另個檔案中( 接收端記錄檔 ), 有了這兩個記錄檔, 我們要求得吞吐量 封包延遲 抖動率 或封包遺失率就變得很簡單了 對於封包遺失率, 我們可以先計算發送端記錄檔中有多少筆記錄, 每一筆記錄就代表一個送出封包的資訊, 因此有多少筆記錄就代表有多少封包被送出, 同理, 我們去計算接收端記錄檔中有多少記錄, 每一筆記錄代表每一個所接収封包的資訊, 因此有多少筆記錄就代表有多少封包被接收, 從這兩個數值的差值我們就可以得知會有多少的封包在傳送的過程被丟棄了, 然後再把這個差值除以全部送出的封包量, 就可以得到封包遺失率 對於封包延遲, 則可以直接從接收端記錄檔的第四欄得到 對於抖動率 (jitter), 則可以使用封包延遲時間差距除以封包序號差距得到 (jitter =( (recvtime(j) - sendtime(j) ) - (recvtime(i) - sendtime(i) ) ) / (j-i) = delay(j) - delay(i) / (j-1), 其中 j>i ) 對於吞吐量, 則可以把所接收的封包大小總和除以所花費的時間就可以得到 若是要求得以 TCP 為傳輸協定的應用程式的吞吐量, 方法也跟 UDP 相同, 直接分析接收端記錄檔的資訊就可以了 實驗步驟 [ 有線網路 ] 模擬環境 : 如下圖所示, 這個網路的環境包含了兩個傳輸節點 s1 和 s2, 路由器 r, 和資料接收端 d s1 到 r 之間與 s2 到 r 之間的網路頻寬都是 2Mbps, 傳遞延遲時間是 10ms 網路架構中的頻寬瓶頸是在 r 到 d 之間, 頻寬為 1.7Mbps, 傳遞延遲的時間為 20ms 所有鏈路的管理機制都是採用 DropTail, 且 r 到 d 之間的最大佇列長度 (queue limit) 是 10 個封包的長度 在 s1 到 d 之間會有一條 FTP 的連線, 另外, 在 s2 到 d 之間有一條 CBR 的連線, 其傳送速度為 1Mbps, 每一個封包大小為 1Kbytes CBR 是在 0.1 秒開始傳送, 在 4.5 秒結束傳輸 ;FTP 是在 1.0
秒開始傳送,4.0 秒結束傳輸 node link agent ftp tcp traffic trace s1 2Mbps, 10ms r 1.7Mbps, 20ms d sink s2 2Mbps, 10ms null udp cbr cbr ftp sec 0.1 1.0 4.0 4.5 TCL 程式碼 ( 光碟中的?.tcl) # 產生一個模擬的物件 set ns [new Simulator] # 針對不同的資料流定義不同的顏色, 這是要給 NAM 用的 $ns color 1 Blue $ns color 2 Red # 開啟一個 NAM 記錄檔 set nf [open out.nam w] $ns namtrace-all $nf # 開啟一個模擬過程記錄檔, 用來記錄封包傳送的過程 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 # 產生傳輸節點, s1 的 id 為 0, s2 的 id 為 1 set s1 [$ns node] set s2 [$ns node] # 產生路由器節點, r 的 id 為 2 set r [$ns node] # 產生資料接收節點, d 的 id 為 3 set d [$ns node] #s1-r 的鏈路具有 2Mbps 的頻寬,10ms 的傳遞延遲時間,DropTail 的佇列管理方式 #s2-r 的鏈路具有 2Mbps 的頻寬,10ms 的傳遞延遲時間,DropTail 的佇列管理方式 #r-d 的鏈路具有 1.7Mbps 的頻寬,20ms 的傳遞延遲時間,DropTail 的佇列管理方式 $ns duplex-link $s1 $r 2Mb 10ms DropTail $ns duplex-link $s2 $r 2Mb 10ms DropTail $ns duplex-link $r $d 1.7Mb 20ms DropTail # 設定 r 到 d 之間的 Queue Limit 為 10 個封包大小 $ns queue-limit $r $d 10 # 設定節點的位置, 這是要給 NAM 用的 $ns duplex-link-op $s1 $r orient right-down $ns duplex-link-op $s2 $r orient right-up $ns duplex-link-op $r $d orient right # 觀測 r 到 d 之間 queue 的變化, 這是要給 NAM 用的 $ns duplex-link-op $r $d queuepos 0.5 # 建立一條 TCP 的連線 set tcp [new Agent/TCP]
$ns attach-agent $s1 $tcp # mtcpsink 是 TCPsink 的延申, 除了具有 TCPSink 的功能外, 也能記錄所送出封包資訊 set sink [new Agent/TCPSink/mTcpSink] # 設定 tcp 接收記錄檔的檔名為 tcp_sink $sink set_filename tcp_sink $ns attach-agent $d $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 # 建立一條 mudp 的連線 #mudp 是 UDP 的延申, 除了具有 UDP 的功能外, 也能記錄所送出封包資訊 set udp [new Agent/mUDP] # 設定傳送記錄檔檔名為 sd_udp $udp set_filename sd_udp $ns attach-agent $s2 $udp # 新增的接收 Agent, 可以把接收封包資訊記錄到檔案中 set null [new Agent/mUdpSink] # 設定接收檔記錄檔檔名為 rd_udp $null set_filename rd_udp $ns attach-agent $d $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 # 設定傳送封包的大小為 1000 byte $cbr set packet_size_ 1000 # 設定傳送的速率為 1Mbps $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 $s1 $tcp ; $ns detach-agent $d $sink" # 在模擬環境中,5 秒後去呼叫 finish 來結束模擬 ( 這樣要注意模擬環境中 # 的 5 秒並不一定等於實際模擬的時間 $ns at 5.0 "finish" # 執行模擬 $ns run 執行方式 : $ns xxx.tcl 模擬結束後就會產生 tcp_sink,sd_udp, 和 rd_udp 三個記錄檔 計算 CBR 的封包遺失率 從 sd_udp 檔案中, 可以得知共有 550 筆記錄 ; 從 rd_udp 檔案中, 可以得知共有 542 筆記錄, 所以共有 8 個封包遺失, 因此封包遺失率就為 8/550 = 1.45% 求得封包延遲時間 $awk `{print $1, $4' rd_udp > cbr_delay 說明 : 使用 awk, 把 rd_udp 檔案中的第一 ( 封包序號 ) 和第四欄 ( 封包延遲時間 ) 列 印到 cbr_delay 的檔案中 使用 gnuplot 畫出 cbr_delay
gnuplot> plot cbr_delay" title `cbr: packet delay'with linespoints 1 gnuplot> set xlabel `packet sequence' gnuplot> set ylabel `delay time (sec)' gnuplot> set terminal gif gnuplot> set output cbr_delay.gif" gnuplot> replot 結果是不是跟第一本計算機網路實驗當中使用 awk 分析原本的記錄檔一樣呢 求得抖動率 awk 分析程式 (measure-jitter.awk) BEGIN{ last_pkt_id = -1; last_e2e_delay = -1; { pkt_id = $1; send_time = $2;
rcv_time = $3; e2e_delay = $4; pkt_size = $5; if( last_pkt_id!=-1) { jitter = (e2e_delay - last_e2e_delay) / (pkt_id - last_pkt_id); printf("%f %f\n", send_time, jitter); { last_pkt_id = pkt_id; last_e2e_delay = e2e_delay; 執行方法 : $awk f measure-jitter.awk rd_udp > cbr_jitter gnuplot> plot cbr_jitter" title `cbr: packet jitter'with linespoints 1 gnuplot> set xlabel `packet start time (sec)' gnuplot> set ylabel `jitter (sec)' gnuplot> set terminal gif gnuplot> set output cbr_jitter.gif" gnuplot> replot
求得吞吐量 Perl 分析 UDP 吞吐量程式 (measure-throughput.pl) # 使用方法 : perl measure-throughput.pl <trace file> <granlarity> # 記錄檔檔名 $infile=$argv[0]; # 多少時間計算一次 ( 單位為秒 ) $granularity=$argv[1]; $sum=0; $sum_total=0; $clock=0; $maxrate=0; $init=0; # 打開記錄檔 open (DATA,"<$infile")
die "Can't open $infile $!"; # 讀取記錄檔中的每行資料, 資料是以空白分成眾多欄位 while (<DATA>) { @x = split(' '); if($init==0){ $start=$x[2]; $init=1; # 讀取的第零個欄位是 pkt_id # 讀取的第一個欄位是封包傳送時間 # 讀取的第二個欄位是封包接收時間 # 讀取的第三個欄位是封包 end to end delay # 讀取的第四個欄位是封包大小 # 判斷所讀到的時間, 是否已經達到要統計吞吐量的時候 if ($x[2]-$clock <= $granularity) { # 計算單位時間內累積的封包大小 $sum=$sum+$x[4]; else { # 計算累積的總封包大小 $sum_total=$sum_total+$x[4]; # 計算吞吐量 $throughput=$sum*8.0/$granularity; if ($throughput > $maxrate){ $maxrate=$throughput; # 輸出結果 : 時間吞吐量 (bps) print STDOUT "$x[2]: $throughput bps\n"; # 設定下次要計算吞吐量的時間
$clock=$clock+$granularity; $sum_total=$sum_total+$x[4]; $sum=$x[4]; $endtime=$x[2]; # 計算最後一次的吞吐量大小 $throughput=$sum*8.0/$granularity; print STDOUT "$x[2]: $throughput bps\n"; $clock=$clock+$granularity; $sum=0; #print STDOUT "$sum_total $start $endtime\n"; $avgrate=$sum_total*8.0/($endtime-$start); print STDOUT "Average rate: $avgrate bps\n"; print STDOUT "Peak rate: $maxrate bps\n"; # 關閉檔案 close DATA; exit(0); 執行的方法 : $perl measure-throughput.pl rd_udp 0.5 執行的結果 : 0.506706: 736000 bps 1.002706: 992000 bps 1.507553: 848000 bps 2.001294: 992000 bps 2.505294: 1040000 bps 3.003553: 960000 bps 3.501906: 1040000 bps 4.000259: 928000 bps 4.506706: 1072000 bps Average rate: 987249.544626594 bps Peak rate: 1072000 bps
說明 : 0.5 指的是每 0.5 秒去統計這段時間的平均的吞吐量 結果中的第一欄是時 間, 第二欄是這段時間內的平均吞吐量 最後還會把全部平均吞吐量的值和最高 的吞吐量顯示出來 計算 TCP 的吞吐量 Perl 分析 TCP 吞吐量程式 (measure-tcp.pl) # 使用方法 : perl measure-tcp.pl <trace file> <granlarity> # 記錄檔檔名 $infile=$argv[0]; # 多少時間計算一次 ( 單位為秒 ) $granularity=$argv[1]; $sum=0; $sum_total=0; $clock=0; $init=0; # 打開記錄檔 open (DATA,"<$infile") die "Can't open $infile $!"; # 讀取記錄檔中的每行資料, 資料是以空白分成眾多欄位 while (<DATA>) { @x = split(' '); if($init==0){ $start=$x[1]; $init=1; # 讀取的第零個欄位是 pkt_id
# 讀取的第一個欄位是封包接收時間 # 讀取的第二個欄位是封包大小 # 判斷所讀到的時間, 是否已經達到要統計吞吐量的時候 if ($x[1]-$clock <= $granularity) { # 計算單位時間內累積的封包大小 $sum=$sum+$x[2]; else { # 計算累積的總封包大小 $sum_total=$sum_total+$x[2]; # 計算吞吐量 $throughput=$sum*8.0/$granularity; # 輸出結果 : 時間吞吐量 (bps) print STDOUT "$x[1] $throughput\n"; # 設定下次要計算吞吐量的時間 $clock=$clock+$granularity; $sum_total=$sum_total+$x[2]; $sum=$x[2]; $endtime=$x[1]; # 計算最後一次的吞吐量大小 $throughput=$sum*8.0/$granularity; print STDOUT "$x[1] $throughput\n"; $clock=$clock+$granularity; $sum=0; print STDOUT "$sum_total $start $endtime\n"; $avgrate=$sum_total*8.0/($endtime-$start); print STDOUT "Average rate: $avgrate bps\n";
# 關閉檔案 close DATA; exit(0); 執行的方法 : $perl measure-tcp tcp_sink 0.5 執行的結果 1.034894 0 1.104296 640 1.502847 615680 2.006188 582400 2.500588 549120 3.008447 732160 3.506800 532480 4.005153 765440 4.072353 133120 Average rate: 624522.010009024 bps [ 無線網路 ] 模擬的範圍區域為 1000m x 1000m, 共有三個 Mobile Nodes 在節點 0 和節點 2 之間有一條 CBR/UDP 的連線 在模擬時間 200 秒的時候, 節點 1 開始從位置 (500, 500) 移動到 (500, 900), 然後在 500 秒的時候, 再從位置 (500, 900) 移動到 (500, 100) 全部的模擬時間為 1000 秒
TCL 程式碼 ( 光碟中的?.tcl) # Define options 定義一些變數 #=========================================================== set val(chan) Channel/WirelessChannel ;# channel type set val(prop) Propagation/TwoRayGround ;#radio-propagation model set val(netif) Phy/WirelessPhy ;# network interface type set val(mac) Mac/802_11 ;# MAC type set val(ifq) Queue/DropTail/PriQueue ;# interface queue type set val(ll) LL ;# link layer type set val(ant) Antenna/OmniAntenna ;# antenna model ( 天線模型 ) set val(x) 1000 ;# 拓樸範圍 :X set val(y) 1000 ;# 拓樸範圍 :Y set val(ifqlen) 50 ;# max packet in ifq set val(nn) 3 ;# number of mobile nodes set val(seed) 0.0 set val(stop) 1000.0 ;# simulation time set val(tr) exp.tr ;# trace file name set val(rp) DSDV ;# routing protocol # Initialize Global Variables
set ns_ [new Simulator] # Open trace file 開啟 trace file $ns_ use-newtrace set namfd [open nam-exp.tr w] $ns_ namtrace-all-wireless $namfd $val(x) $val(y) set tracefd [open $val(tr) w] $ns_ trace-all $tracefd # set up topography object # 建立一個拓樸物件, 以紀錄 mobilenodes 在拓樸內移動的情況 set topo [new Topography] # 拓樸的範圍為 1000m x 1000m $topo load_flatgrid $val(x) $val(y) # create channel set chan [new $val(chan)] # Create God set god_ [create-god $val(nn)] # Create the specified number of mobile nodes [$val(nn)] and "attach" them # to the channel. Three nodes are created : node(0), node(1) and node(2) # 設置 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 \ -agenttrace ON \ -routertrace ON \ -mactrace OFF \
-movementtrace OFF for {set i 0 {$i < $val(nn) {incr i { set node_($i) [$ns_ node] $node_($i) random-motion 0 ;# disable random motion # Provide initial (X,Y, for now Z=0) co-ordinates for mobilenodes # # 設定節點 0 在一開始時, 位置在 (350.0, 500.0) $node_(0) set X_ 350.0 $node_(0) set Y_ 500.0 $node_(0) set Z_ 0.0 # 設定節點 1 在一開始時, 位置在 (500.0, 500.0) $node_(1) set X_ 500.0 $node_(1) set Y_ 500.0 $node_(1) set Z_ 0.0 # 設定節點 2 在一開始時, 位置在 (650.0, 500.0) $node_(2) set X_ 650.0 $node_(2) set Y_ 500.0 $node_(2) set Z_ 0.0 # Load the god object with shortest hop information # 在節點 1 和節點 2 之間最短的 hop 數為 1 $god_ set-dist 1 2 1 # 在節點 0 和節點 2 之間最短的 hop 數為 2 $god_ set-dist 0 2 2 # 在節點 0 和節點 1 之間最短的 hop 數為 1 $god_ set-dist 0 1 1 # Now produce some simple node movements # Node_(1) starts to move upward and then downward set god_ [God instance]
# 在模擬時間 200 秒的時候, 節點 1 開始從位置 (500, 500) 移動到 (500, 900), # 速度為 2.0 m/sec $ns_ at 200.0 "$node_(1) setdest 500.0 900.0 2.0" # 然後在 500 秒的時候, 再從位置 (500, 900) 移動到 (500, 100), 速度為 2.0 m/sec $ns_ at 500.0 "$node_(1) setdest 500.0 100.0 2.0" # Setup traffic flow between nodes 0 connecting to 2 at time 100.0 # 在節點 0 和節點 2 建立一條 CBR/UDP 的連線, 且在時間為 100 秒開始傳送 set udp_(0) [new Agent/mUDP] # 設定傳送記錄檔檔名為 sd_udp $udp_(0) set_filename sd_udp $udp_(0) set fid_ 1 $ns_ attach-agent $node_(0) $udp_(0) set null_(0) [new Agent/mUdpSink] # 設定接收檔記錄檔檔名為 rd_udp $null_(0) set_filename rd_udp $ns_ attach-agent $node_(2) $null_(0) set cbr_(0) [new Application/Traffic/CBR] $cbr_(0) set packetsize_ 200 $cbr_(0) set interval_ 2.0 $cbr_(0) set random_ 1 $cbr_(0) set maxpkts_ 10000 $cbr_(0) attach-agent $udp_(0) $ns_ connect $udp_(0) $null_(0) $ns_ at 100.0 "$cbr_(0) start" #Define node initial position in nam, only for nam # 在 nam 中定義節點初始所在位置 for {set i 0 {$i < $val(nn) {incr i { # The function must be called after mobility model is defined. $ns_ initial_node_pos $node_($i) 60 # 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" proc stop { { global ns_ tracefd namfd $ns_ flush-trace close $tracefd close $namfd puts "Starting Simulation..." $ns_ run 執行方式 : $ns xxx.tcl 模擬結束後就會產生 sd_udp 和 rd_udp 兩個記錄檔 計算 CBR 的封包遺失率 從 sd_udp 檔案中, 可以得知共有 455 筆記錄 ; 從 rd_udp 檔案中, 可以得知共有 195 筆記錄, 所以共有 260 個封包遺失, 因此封包遺失率就為 260/455 = 57.14% 求得封包延遲時間 $awk `{print $1, $4' rd_udp > cbr_delay 使用 gnuplot 畫出 cbr_delay gnuplot> plot cbr_delay" title `cbr: packet delay'with linespoints 1 gnuplot> set xlabel `packet sequence' gnuplot> set ylabel `delay time (sec)' gnuplot> set terminal gif gnuplot> set output cbr_delay.gif" gnuplot> replot
計算抖動率 執行方法 : $awk f measure-jitter.awk rd_udp > cbr_jitter gnuplot> plot cbr_jitter" title `cbr: packet jitter'with linespoints 1 gnuplot> set xlabel `packet start time (sec)' gnuplot> set ylabel `jitter (sec)' gnuplot> set terminal gif gnuplot> set output cbr_jitter.gif" gnuplot> replot
計算吞吐量 執行的方法 : $perl measure-throughput.pl rd_udp 1 執行的結果 Average rate: 492.73 bps 習題 1. 把無線網路實驗中的 CBR, 改成 TCP, 並量測其平均吞吐量 參考資料 1. http://nsnam.isi.edu/nsnam/index.php/ns-2_trace_formats p.s. 讀者可以先下載安裝 myns2, 就可以直接使用文章中的那些功能作者 : 柯志亨 (Chih-Heng, Ke) Email: smallko@ee.ncku.edu.tw