26. 2. Extending NS in C++
การแกไข Code C++
2.1 ใชคําสั่ง “make clean”
2.2 ใชคําสั่ง “make” เพื่อที่จะทําการ compile .o ทั้งหมดอีกครั้ง
การสราง Network Object ดวย C++ เขาไปใน NS
การสราง network object ใหมโดยใชภาษา C++ นั้นจะตองมีการสรางการเชื่อมโยงระหวางตัวแปร
ใน Otcl และตัวแปรในภาษา C++ เพื่อที่เวลาใช Otcl script แลว NS2 จะสามารถที่จะคนหาตัวแปรแลว
match กับคําสั่งที่มีแลวทําการแสดงผลได ซึ่งจะตองนํา file ที่เปน code ภาษา C++ เขาไปไวในโปรแกรม
NS2 ขั้นตอนของการสราง Network object มีดังนี้
1. Export C++ class to OTcl
2. Export C++ class variables to OTcl
3. Export C++ Object Control Commands to OTcl
4. Execute an OTcl command from C++
5. Compile and Run
ตัวอยางของการสราง Network object (MyAgent)
Step1. Export C++ class to OTcl
เราสราง network object class ชื่อวา MyAgent ซึ่ง derive มาจาก Class Agent ใน C++ โดย Class
MyAgent นี้จะทําการสรางตัวแทนของ Object นี้ไวใน Otcl ซึ่งการที่จะทําเชนนี้ไดจะตองนิยาม linkage
object เปนตัวกลางในการเชื่อมตอ โดยสราง Class MyAgentClass ขึ้นมา ซึ่ง Class MyAgentClass นั้น
derive มาจาก Class Tclclass ซึ่ง linkage object นี้จะทําการสราง OTcl object ที่มีชื่อวา
“Agent/MyAgentOtcl” (ในตัวอยางนี้) และสราง Linkageระหวาง OTcl object และ C++ object ที่เปนตัว
สราง object ซึ่งในที่นี้ คือ MyAgent
26
27. เมื่อ NS เริ่มทํางานจะมีการเรียก constructor ของตัวแปร static ที่ชื่อวา class_my_agent แลวจึงสราง
ตัวแทนของ “MyAgentClass” ขึ้น Class Agent/MyAgentOtcl และ method ตางๆจะถูกสรางไวใน OTcl
space เมื่อใดที่ User ใน Otcl พยายามที่จะการสรางตัวแทนของ Object จะทําไดโดยใชคําสั่ง “new
Agent/MyAgentOtcl” ซึ่งจะมีการเรียก Method “MyAgentClass::create” เพื่อสรางตัวแทนของ “MyAgent”
และ สงคา address กลับไป ในการสราง Object ใน C++ จาก OTcl นั้นจะไมไดคุณสมบัติ function หรือ
member variable ของ C++ จาก OTcl
Step 2. Export C++ class variables to OTcl
สมมติวา C ++ Object “MyAgent” ที่เราสรางใหมขึ้นมา มี parameter 2 ตัว คือ “my_var1” และ
“my_var2” ซึ่งเราตองการที่จะ configure จาก OTcl โดยใช input simulation script เราจะใช binding
function ทําการ binding แตละตัวแปรของ ClassในC++ ที่เราตองการที่จะสงคาออกไป ซึ่ง binding function
นั้น จะทําการสรางตัวแปรขึ้นมา (ชื่อตาม my_var1) โดยจะนําไป match กับ OTcl object ของ class
(“Agent/MyAgentOtcl”) และทําการ binding แบบ bi-directional ระหวางตัวแปรของ OTcl class กับตัวแปร
ของ C++ ที่มี address ตรงกับ my_var1 และ my_var2 ตามลําดับ
ภาพที่ 3.6 แสดงการทํางานแบบ Bidirectional binding
27
28. Binding function จะอยูใน constructor function เพื่อใชในการ binding ตอนที่ instance ของ object นี้ถูก
สรางขึ้น ซึ่ง N S สนับสนุนฟงกชั่น B i n d i n g 4 แบบที่เหมาะสําหรับ D a t a t y p e 5 แบบดังนี้
- bind(): real or integer variables
- bind_time(): time variable
- bind_bw(): bandwidth variable
- bind_bool(): boolean variable
ดังนั้น User designing และ running simulation ที่ใช OTcl Script จะสามารถ configure parameter
ที่สรางใน C++ ได
Step 3. Export C++ Object Control Commands to OTcl
การ export C++ object variable ที่ User สรางนั้น เราจึงตองกําหนดให control ของ C++ Object ไป
อยูใน OTcl ซึ่งจะทําได โดยใหเรา define “command” member function ของ C++ object (“MyAgent”)
เพื่อที่จะทําหนาที่เปนตัว interpreter ของ OTcl ซึ่ง “command” member function จะทําการคนหา Member
function ที่ Match กับ OTcl object ใหกับ User
เมื่อ instance ของ the shadow OTcl นั้น ทําการ Match “MyAgent” object ที่ถูกสรางใน Otcl space
(set myagent [new Agent/MyAgentOtcl]) แลว และ User ทําการเรียก Member function ของ object
($myagent call-my-priv-func), OTcl จะคนหา Member function ที่ User ตองการใน OTcl object ถาชื่อ
Member function ที่ใหมาหาไมเจอมันจะเรียก “MyAgent :: command” แลวสงคาชื่อของ OTcl member
function ที่เรียก และ argument ไปในรูปแบบของ argc/argv แตถาหาเจอ และมี action มารองรับ มัน
จะทํา action และทําการ return ผลลัพธกลับไปและเรียก function ถาไมมี “command” function ของ object
บรรพบุรุษมันจะทํา recursive หาจนกวาจะพบ แตถาหาชื่อนั้นไมพบในบรรพบุรุษไหนเลย ก็จะมี error
message สงไปให OTcl object และ OTcl object จะแสดง error message ใหกับ User
28
29. Step 4. Execute an OTcl command from C++
เมื่อเราตองการที่จะสราง network object ใหม เราจึงจําเปนที่จะตองมีการ Execute คําสั่งของ OTcl
จาก C++ object จากภาพดานลางเปนตัวอยางของการ implement “MyPrivFunc” ซึ่งเปน member
function ของ “MyAgent” ซึ่งเปนการแสดงผลลัพธของคาของ my_var1 และ my_var2 ออกทางหนาจอ
ซึ่งการที่จะ Execute คําสั่งของ OTcl จาก C++ นั้นเราตองมีการอางถึง “Tcl::instance()” ซึ่งถูกประกาศ
เปน static member variable ซึ่งในตัวอยางนี้ไดแสดงการสงคําสั่ง OTcl ใหกับ interpreter ซึ่งมี 2 ทาง
คือ MyPrivFunc และ Tcl::instance()
Step 5. Compile and Run and Test “MyAgent”
1. บันทึก ชื่อfile.cc ที่ตองการจะสราง Network Object เชน ex-linkage.cc แลวบันทึกไวใน NS-2
directory
2. เปด “Makefile” แลวทําการเพิ่ม ชื่อfile.o (เชน ex-linkage.o) ไวในบรรทัดสุดทายของObject file
list
OBJ_CC =
…
./ex-linkage.o
$(OBJ_STL)
3. Re-compile NS โดยใชคําสั่ง “make”
4. สราง file.tcl ขึ้นมาเพื่อทดสอบการทํางานของ Network Object ที่สรางขึ้น
5. run Otcl script โดยใชคําสั่ง ns ชื่อfile.tcl
Download ex-linkage.cc : http://nile.wpi.edu/NS/Example/ex-linkage.cc
Download ex-linkage.tcl : http://nile.wpi.edu/NS/linkage.html
29
32. Chapter 4
Visualization Tools
4.1 nam-1 (Network AniMator Version 1)
Nam เปน Animation tool ที่มีพื้นฐานมาจาก Tcl/TK มีไวสําหรับแสดงการจําลองการทํางาน ของ
network และ packet ซึ่งแสดงผลออกมาในรูปของภาพกราฟฟกโดยไปดึงขอมูลที่ใชในการจําลอง Network
จาก nam teace file ที่ไดสรางไวจากใน Tcl Script ซึ่ง Nam ไดสนับสนุน topology latout, packet level
animation และ เครื่องมือในการตรวจสอบขอมูล
Run Nam
nam <nam-file>
nam out.nam
Run Nam in Ns2 script
exec nam <nam-file>
exec nam out.nam
Nam Interface
1. Color mapping
$ns color fid <color> : เปนการกําหนดสีใหกับ packet ตามเสนทางการเดินทางโดยใช flow id
(fid) เปนตัวบงบอก
COLOR : red, blue เปนตน
$ns color 40 red
$ns color 41 blue
2. Color flow id association
$<variable of agent> set fid_ <variable of color>
$tcp0 set fid_ 40 # red packets แสดงวา 40 = สีแดง
3. Node Color เปนการกําหนดสีใหกับ node
$<variable of node> color <COLOR>
COLOR : red, blue เปนตน
$node color red #nodeนี้จะมีสีเปนสีแดง
32
33. 4. Node Shape เปนการกําหนดรูปรางใหกับ node
$<variable of node> shape <SHAPE>
SHAPE : circle, box, hexagon เปนตน
$node shape box
5. Node Marks เปนการเพิ่มและลบ node ที่มีการ mark ไวตามเวลาที่กําหนด
$ns at 1.0 “$n0 add-mark m0 blue box”
$ns at 2.0 “$n0 delete-mark m0”
เมื่อกําหนดเชนนี้เวลาแสดงผลจะปรากฎ Mask ตามที่ระบุภายในชวงเวลา 1-2 วินาที
6. Node Lable เปนการกําหนดขอความกํากับที่ node เริ่มตั้งแตชวงเวลาที่กําหนด
$ns at 1.1 “$n0 label ”web cache 0””
7. Link Color เปนการกําหนดสีของlink จาก Node หนึ่งไปยังอีก Node
$ns duplex-link-op $n0 $n1 color quot;greenquot;
8. Link Label เปนการกํากับขอความบน link ที่อยูระหวาง node 2 node ที่กาหนด
ํ
$ns duplex-link-op $n0 $n1 label “backbonequot;
ภาพที่ 4.1 แสดงหนาจอที่มีการเรียกใช Nam
33
36. จากนั้นทําการสราง traffic ขึ้นมาเพื่อเพิ่มเติมรายละเอียดใหกับ node ดังกลาว โดยในสวนนี้จะเขียน
อยูในรูปของฟงกชันซึ่งมีชื่อวา attach-expoo-traffic และมีการรับคาจาก parameter 6 คาซึ่งคือ
node,sink,size,burst,idle,rate เพื่อความสะดวกในการกําหนดรายละเอียดของ node นั้น ๆ
proc attach-expoo-traffic { node sink size burst idle rate } {
#Get an instance of the simulator
set ns [Simulator instance]
#Create a UDP agent and attach it to the node
set source [new Agent/UDP]
$ns attach-agent $node $source
#Create an Expoo traffic agent and set its
configuration parameters
set traffic [new Application/Traffic/Exponential]
$traffic set packetSize_ $size
$traffic set burst_time_ $burst
$traffic set idle_time_ $idle
$traffic set rate_ $rate
# Attach traffic source to the traffic generator
$traffic attach-agent $source
#Connect the source and the sink
$ns connect $source $sink
return $traffic
}
จากตัวอยางฟงกชันดังกลาวนี้ จะมีอยูทั้งหมด 6 arguments
1. node คือ node ที่มีการสรางไวขางตน
2. sink คือ ตัวแปรของ traffic sink ที่สรางขึ้น
3. size คือ ขนาดของ packet ของ traffic source
4. burst คือ burst time
5. idle คือ idle time
6. rate คือ burst peak rate
จากรายละเอียดของฟงกชันนี้จะสราง traffic ขึ้นมาและทําการ attaches เขาไปภายใน node และมี
การสราง traffic object ซึ่งจากการสราง Traffic/Expoo object จะสามารถระบุการตั้งคาตาง ๆ ใหกับ traffic
object ไดโดยการรับคามาจาก parameters ซึ่งคาที่จะสงมากับ parameter นั้นมาจากการสรางขึ้นมากับ traffic
source และมีการ attach traffic เขาไปใน source รวมทั้งยังมีการ connect ระหวาง source และ sink ดวย
สวนตอไปนี้คือการสราง traffic เพื่อสรางความแตกตางกันของคา peak rates ภายใน node n0 , n1
และ n2 และจากนั้นจะเชื่อมโยง 3 traffic sink ไปยัง node n4
36
37. set sink0 [new Agent/LossMonitor] * ในสวนนี้ใช Agent/LossMonitor
set sink1 [new Agent/LossMonitor]
set sink2 [new Agent/LossMonitor] objects ในการสราง traffic sinks เพื่อ
$ns attach-agent $n4 $sink0
$ns attach-agent $n4 $sink1 นํามาชวยในการเก็บจํานวน bytes ที่ได
$ns attach-agent $n4 $sink2
มีการรับเขามา ซึ่งจะมีสวนชวยในการ
set source0 [attach-expoo-traffic $n0 $sink0 200 2s 1s 100k]
set source1 [attach-expoo-traffic $n1 $sink1 200 2s 1s 200k] คํานวณหา bandwidth
set source2 [attach-expoo-traffic $n2 $sink2 200 2s 1s 300k]
2. Recording Data in Output Files
ในสวนแรกนีจะทําการเปด output files ขึ้นมา 3 files จาก Tcl script ตามตัวอยางตอไปนี้
้
set f0 [open out0.tr w]
set f1 [open out1.tr w]
set f2 [open out2.tr w]
สรางฟงกชันเพื่อจบการทํางานของโปรแกรมดังนี้
proc finish {} {
global f0 f1 f2
#Close the output files
close $f0
close $f1
close $f2
#Call xgraph to display the results
exec xgraph out0.tr out1.tr out2.tr -geometry 800x400 &
exit 0
}
37
38. จากฟงกชันนี้ไมเพียงแตปดการทํางานของ output files แตจะเปนการเรียกการทํางานของ Xgraph
ขึ้นมาเพื่อแสดงผลลัพธดวยตามขนาดของ size window ที่ 800*400 ที่หนาจอ screen
proc record {} {
global sink0 sink1 sink2 f0 f1 f2
#Get an instance of the simulator
set ns [Simulator instance]
#Set the time after which the procedure should be called again
set time 0.5
#How many bytes have been received by the traffic sinks?
set bw0 [$sink0 set bytes_]
set bw1 [$sink1 set bytes_]
set bw2 [$sink2 set bytes_]
#Get the current time
set now [$ns now]
#Calculate the bandwidth (in MBit/s) and write it to the files
puts $f0 quot;$now [expr $bw0/$time*8/1000000]quot;
puts $f1 quot;$now [expr $bw1/$time*8/1000000]quot;
puts $f2 quot;$now [expr $bw2/$time*8/1000000]quot;
#Reset the bytes_ values on the traffic sinks
$sink0 set bytes_ 0
$sink1 set bytes_ 0
$sink2 set bytes_ 0
#Re-schedule the procedure
$ns at [expr $now+$time] quot;recordquot;
}
จากฟงกชันกอนหนานี้จะทําการอานจํานวนของ Bytes จากสาม traffic sinks ที่ถูกเก็บไวจาก object
ของ Agent/LossMonitor และจากนั้นจะทําการคํานวณ Bandwidth ในหนวยของ MBits/sec และจะเขียน
ขอมูลที่เปนเวลาปจจุบันและคา Bandwidth ที่คํานวณไดลงในแตละ output files ไปดวยกันกอนที่จะทําการ
reset คาของ bytes_value ที่ traffic sinks
3. Running the Simulation
มาถึงในสวนนี้ จะได schedule ขึ้นมาจากกลุมคําสั่งตอไปนี้ และทําการรันโปรแกรมขึ้นมาตาม
ตารางเวลาดังกลาวนี้
$ns at 0.0 quot;recordquot;
$ns at 10.0 quot;$source0 startquot;
Result
$ns at 10.0 quot;$source1 startquot;
$ns at 10.0 quot;$source2 startquot;
$ns at 50.0 quot;$source0 stopquot;
$ns at 50.0 quot;$source1 stopquot;
$ns at 50.0 quot;$source2 stopquot;
$ns at 60.0 quot;finishquot;
$ns run
38
39. ภาพที่ 4.3 แสดงผลการทํางานของ Xgraph
Source Code
#Create a simulator object
set ns [new Simulator]
#Open the output files
set f0 [open out0.tr w]
set f1 [open out1.tr w]
set f2 [open out2.tr w]
#Create 5 nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
#Connect the nodes
$ns duplex-link $n0 $n3 1Mb 100ms DropTail
$ns duplex-link $n1 $n3 1Mb 100ms DropTail
$ns duplex-link $n2 $n3 1Mb 100ms DropTail
$ns duplex-link $n3 $n4 1Mb 100ms DropTail
#Define a 'finish' procedure
proc finish {} {
global f0 f1 f2
#Close the output files
close $f0
close $f1
close $f2
#Call xgraph to display the results
exec xgraph out0.tr out1.tr out2.tr -geometry 800x400 &
exit 0
}
39
40. #Define a procedure that attaches a UDP agent to a previously created node
#'node' and attaches an Expoo traffic generator to the agent with the
#characteristic values 'size' for packet size 'burst' for burst time,
#'idle' for idle time and 'rate' for burst peak rate. The procedure
connects
#the source with the previously defined traffic sink 'sink' and returns the
#source object.
proc attach-expoo-traffic { node sink size burst idle rate } {
#Get an instance of the simulator
set ns [Simulator instance]
#Create a UDP agent and attach it to the node
set source [new Agent/UDP]
$ns attach-agent $node $source
#Create an Expoo traffic agent and set its configuration parameters
set traffic [new Application/Traffic/Exponential]
$traffic set packetSize_ $size
$traffic set burst_time_ $burst
$traffic set idle_time_ $idle
$traffic set rate_ $rate
# Attach traffic source to the traffic generator
$traffic attach-agent $source
#Connect the source and the sink
$ns connect $source $sink
return $traffic
}
#Define a procedure which periodically records the bandwidth received by
the
#three traffic sinks sink0/1/2 and writes it to the three files f0/1/2.
proc record {} {
global sink0 sink1 sink2 f0 f1 f2
#Get an instance of the simulator
set ns [Simulator instance]
#Set the time after which the procedure should be called again
set time 0.5
#How many bytes have been received by the traffic sinks?
set bw0 [$sink0 set bytes_]
set bw1 [$sink1 set bytes_]
set bw2 [$sink2 set bytes_]
#Get the current time
set now [$ns now]
#Calculate the bandwidth (in MBit/s) and write it to the files
puts $f0 quot;$now [expr $bw0/$time*8/1000000]quot;
puts $f1 quot;$now [expr $bw1/$time*8/1000000]quot;
puts $f2 quot;$now [expr $bw2/$time*8/1000000]quot;
#Reset the bytes_ values on the traffic sinks
$sink0 set bytes_ 0
$sink1 set bytes_ 0
$sink2 set bytes_ 0
#Re-schedule the procedure
$ns at [expr $now+$time] quot;recordquot;
}
#Create three traffic sinks and attach them to the node n4
set sink0 [new Agent/LossMonitor]
set sink1 [new Agent/LossMonitor]
set sink2 [new Agent/LossMonitor]
$ns attach-agent $n4 $sink0
$ns attach-agent $n4 $sink1
40
41. $ns attach-agent $n4 $sink2
#Create three traffic sources
set source0 [attach-expoo-traffic $n0 $sink0 200 2s 1s 100k]
set source1 [attach-expoo-traffic $n1 $sink1 200 2s 1s 200k]
set source2 [attach-expoo-traffic $n2 $sink2 200 2s 1s 300k]
#Start logging the received bandwidth
$ns at 0.0 quot;recordquot;
#Start the traffic sources
$ns at 10.0 quot;$source0 startquot;
$ns at 10.0 quot;$source1 startquot;
$ns at 10.0 quot;$source2 startquot;
#Stop the traffic sources
$ns at 50.0 quot;$source0 stopquot;
$ns at 50.0 quot;$source1 stopquot;
$ns at 50.0 quot;$source2 stopquot;
#Call the finish procedure after 60 seconds simulation time
$ns at 60.0 quot;finishquot;
#Run the simulation
$ns run
41