Sunday, October 26, 2008

ns2 wired simulation with tcp, cbr, vbr


Hello, this is for ns2 beginners to finish your homework.

project description and topology is here:

Wired networking in NS-2

You are to implement network fed with TCP traffic and background traffic. The objective of this project is to observe the performance of TCP when the bottleneck link is shared by the background traffic.

-The reference network model is shown in Figure 1, which is a simple network consisting of 8 nodes (node 2 and node 5 can be also seen as routers). The queue size of the link between node 2 and node 5 is limited to 12 packets, and all other links have a limitation of 50 queue size.

-Create FTP traffic on top of a TCP connection between node 1 and node 6 (TCP Reno). The TCP connection’s maximum congestion window size is 40 packets, and the packet size is 280 bytes. Make sure the minimum timeout period of the TCP is set to 0.2 second. The FTP starts at 0.0 second and ends at 15 seconds.

-Add CBR traffic on top of a UDP connection between node 0 and node 6. The CBR service generates and sends packets at the rate of 100 packets per second. The CBR source starts at 2.0 second and lasts for 7 seconds.

-Add a VBR video traffic with rate of 600kbps between node 3 and node 6, use On/Off exponential traffic, set On period as 150ms, and Off period as 100ms. The size of each CBR and VBR packet is 280 bytes. The VBR starts at 7.0 seconds and ends at 11 seconds.

The congestion window size should be monitored and plotted over the time. The bandwidth (here the bandwidth is defined to be the number bytes received over a given time interval, say 0.5 seconds) of CBR and VBR traffic should also monitored and plotted during the entire simulation time. The average throughput of TCP, CBR, and VBR should also be obtained. For the throughput calculation of TCP, the NS-2 trace file will need to be examined by using a script or a programming language (e.g. awk, perl, java, c/c++ or matlab).


1st phase: I assume that you already installed NS2. Go to Ns2 by " cd ns2". Now create a main file that runs the simulation and prints the results to "out.nam" file.


Main file is this:

#Create a simulator object
set ns [new Simulator]

#Define different colors for data flows
$ns color 1 Blue
$ns color 2 Red
$ns color 3 Chocolate
$ns color 4 Brown
$ns color 5 Tan
$ns color 6 Gold

#Open the output files
set f0 [open CBR_MB.tr w]
set f1 [open VBR_MB.tr w]
set f3 [open out3.tr w]




#Open the nam trace file
set nf [open out.nam w]
$ns namtrace-all $nf

#Define a 'finish' procedure
proc finish {} {
global ns nf f0 f1 f3
$ns flush-trace
#Close the trace file
close $nf
#Close the output files
close $f0
close $f1
close $f3
#Call xgraph to display the results
exec xgraph CBR_MB.tr VBR_MB.tr -geometry 800x400 &
exec xgraph out3.tr -geometry 800x400 &

#Execute nam on the trace file
exec nam out.nam &
exit 0
}


#Create four nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
set n5 [$ns node]
set n6 [$ns node]


#Create links between the nodes
$ns duplex-link $n0 $n2 3Mb 1ms DropTail
$ns duplex-link $n1 $n2 5Mb 1ms DropTail
$ns duplex-link $n3 $n2 5Mb 1ms SFQ
$ns duplex-link $n2 $n5 1Mb 5ms DropTail
$ns duplex-link $n5 $n4 4Mb 1ms DropTail
$ns duplex-link $n5 $n6 3Mb 1ms SFQ
$ns queue-limit $n1 $n2 50;
$ns queue-limit $n2 $n5 12;
$ns queue-limit $n0 $n2 50;
$ns queue-limit $n3 $n2 50;
$ns queue-limit $n5 $n4 50;
$ns queue-limit $n5 $n6 50;

$ns duplex-link-op $n0 $n2 orient right
$ns duplex-link-op $n1 $n2 orient down
$ns duplex-link-op $n3 $n2 orient up
$ns duplex-link-op $n2 $n5 orient right
$ns duplex-link-op $n5 $n4 orient right-up
$ns duplex-link-op $n5 $n6 orient right-down


#Monitor the queue for the link between node 2 and node 3
$ns duplex-link-op $n2 $n5 queuePos 0.5
$ns duplex-link-op $n1 $n2 queuePos 0.5
$ns duplex-link-op $n0 $n2 queuePos 0.5
$ns duplex-link-op $n5 $n6 queuePos 0.5
$ns duplex-link-op $n3 $n2 queuePos 0.5


#Create a UDP agent and attach it to node n0
set udp0 [new Agent/UDP]
$udp0 set class_ 1
$ns attach-agent $n0 $udp0

#Create a CBR traffic source and attach it to udp0
set cbr0 [new Application/Traffic/CBR]
$cbr0 set interval_ 0.01
$cbr0 set packetSize_ 280

$cbr0 attach-agent $udp0

#Create a TCP agent and attach it to node n1 --1 to 6
# setup TCP connections
set tcp1 [new Agent/TCP/Reno]
$tcp1 set fid_ 2
$tcp1 set window_ 40

$tcp1 set packetSize_ 280
$tcp1 set minrto_ 0.2
set sink3 [new Agent/TCPSink]
$ns attach-agent $n1 $tcp1
$ns attach-agent $n6 $sink3
$ns connect $tcp1 $sink3
set ftp1 [new Application/FTP]
$ftp1 attach-agent $tcp1




#Create a UDP agent and attach it to node3
set udp1 [new Agent/UDP]
$udp1 set class_ 3
$ns attach-agent $n3 $udp1

# Create a VBR traffic source and attach it to node3
set vbr1 [new Application/Traffic/Exponential]
$vbr1 set packetSize_ 280
$vbr1 set rate_ 600k
$vbr1 set burst_time_ 150ms
$vbr1 set idle_time_ 100ms
$vbr1 attach-agent $udp1

proc plotWindow {tcpsource} {
global ns f3
set time 0.01
set now [$ns now]
set cwnd [$tcpsource set cwnd_]
puts $f3 "$now $cwnd"
$ns at [expr $now+$time] "plotWindow $tcpsource"
}

#Define a procedure which periodically records the bandwidth received by the
#two traffic sinks sink0/1 and writes it to the three files f0/1.
proc record {} {
global sink0 sink1 f0 f1
#Get an instance of the simulator
set ns [Simulator instance]
#Set the time after which the procedure should be called again
set time 0.05
#How many bytes have been received by the traffic sinks?
set bw0 [$sink0 set bytes_]
set bw1 [$sink1 set bytes_]
#Get the current time
set now [$ns now]
#Calculate the bandwidth (in MBit/s) and write it to the files
puts $f0 "$now [expr $bw0/$time*8/1000000]"
puts $f1 "$now [expr $bw1/$time*8/1000000]"
#Reset the bytes_ values on the traffic sinks
$sink0 set bytes_ 0
$sink1 set bytes_ 0
#Re-schedule the procedure
$ns at [expr $now+$time] "record"
}

#Create 2 Loss monitors (a traffic sink) and attach them to node n6
set sink0 [new Agent/LossMonitor]
$ns attach-agent $n6 $sink0
set sink1 [new Agent/LossMonitor]
$ns attach-agent $n6 $sink1


#Connect the traffic sources with the traffic sink
$ns connect $udp0 $sink0
$ns connect $udp1 $sink1



#Start logging the received bandwidth
$ns at 0.0 "record"
$ns at 0.0 "plotWindow $tcp1"

#Schedule events for the CBR agents
$ns at 2.0 "$cbr0 start"
$ns at 0.0 "$ftp1 start"
$ns at 7.0 "$vbr1 start"


#Call the finish procedure after 5 seconds of simulation time
$ns at 7.0 "$cbr0 stop"
$ns at 15.0 "$ftp1 stop"
$ns at 11.0 "$vbr1 stop"
$ns at 18.0 "finish"

#Run the simulation
$ns run
Second phase: Name this file myexample.tcl. In ns2 directory enter this command : "ns myexample.tcl".


Now you should see two Xgraph windows and a simulation window (nam window)


Third phase: Now you have a file called out.nam in the ns2 directory. When you find awk scripts on internet, they always have different nam versions so you can not make anything out of what they wrote. To show you what is inside my out.nam, i am writing a brief section of it here:


this is from out.nam file:


+ -t 0.0240533333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 2 -a 2 -x {1.0 6.0 1 ------- null}

- -t 0.0240533333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 2 -a 2 -x {1.0 6.0 1 ------- null}

h -t 0.0240533333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 2 -a 2 -x {1.0 6.0 -1 ------- null}

r -t 0.0259066666666667 -s 5 -d 6 -p tcp -e 320 -c 2 -i 2 -a 2 -x {1.0 6.0 1 ------- null}

+ -t 0.0259066666666667 -s 6 -d 5 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 1 ------- null}

- -t 0.0259066666666667 -s 6 -d 5 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 1 ------- null}

h -t 0.0259066666666667 -s 6 -d 5 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 -1 ------- null}

r -t 0.0266133333333333 -s 2 -d 5 -p tcp -e 320 -c 2 -i 3 -a 2 -x {1.0 6.0 2 ------- null}

+ -t 0.0266133333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 3 -a 2 -x {1.0 6.0 2 ------- null}

- -t 0.0266133333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 3 -a 2 -x {1.0 6.0 2 ------- null}

h -t 0.0266133333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 3 -a 2 -x {1.0 6.0 -1 ------- null}

r -t 0.0270133333333333 -s 6 -d 5 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 1 ------- null}

+ -t 0.0270133333333333 -s 5 -d 2 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 1 ------- null}

- -t 0.0270133333333333 -s 5 -d 2 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 1 ------- null}

h -t 0.0270133333333333 -s 5 -d 2 -p ack -e 40 -c 2 -i 4 -a 2 -x {6.0 1.0 -1 ------- null}

r -t 0.0284666666666667 -s 5 -d 6 -p tcp -e 320 -c 2 -i 3 -a 2 -x {1.0 6.0 2 ------- null}

+ -t 0.0284666666666667 -s 6 -d 5 -p ack -e 40 -c 2 -i 5 -a 2 -x {6.0 1.0 2 ------- null}

- -t 0.0284666666666667 -s 6 -d 5 -p ack -e 40 -c 2 -i 5 -a 2 -x {6.0 1.0 2 ------- null}

h -t 0.0284666666666667 -s 6 -d 5 -p ack -e 40 -c 2 -i 5 -a 2 -x {6.0 1.0 -1 ------- null}



In this part there are only TCP and TCP acknowledgment packets, but real out.nam file is like 12 MB. It has cbr and vbr too. so what those letters actually mean?:

r:received, +:queued, -:dequeued, h:routed, d:dropped

lets interpret the first line.

+ -t 0.0240533333333333 -s 5 -d 6 -p tcp -e 320 -c 2 -i 2 -a 2 -x {1.0 6.0 1 ------- null}

this says: packet queued, at time 0.0240533333333333, from source node 5, to destination node 6, protocol is TCp, packet size is 320 bytes, flow id (-c) is 2(cbr and vbr do not have flow id), packet number is (-i) 2. rest is comment and you do not need to know.

also before writing awk scripts, see this. each element in this row is numbered like $1, $2, $3. So time is the third element in the row and it is $3. status is $1 (r, t, +,-, d). flow id is $15.

fourth phase: write an awk script to calculate average delay. Call this awk file delay.awk.

Delay.awk is that:

BEGIN {
j = 0
}

if (($1 == "+")&&($9 == "tcp")){

if (1stdelay[$15]>$3) { 1stdelay[$15]=$3 }

}

if (($1 == "r")&&($9 == "tcp")){


if ($3 >rectime[$15]) { rectime[$15]=$3 }


for (i in rectime)
{
j+=1
total= rectime[i]-1stdelay[i]}
average=total/i
}
END {
printf("Average delay is %g seconds\n",average)
}


now go to ns2 directory and enter this command: awk -f delay.awk out.nam

this gives you the average delay.

fifth phase: instantenous delay and throughput: files are here:
name for throughput file: tr.awk

BEGIN { recv=0
tcpreceiveddata=0
tcpatdata=0
tcpack=0
acksize=0
tcpreceivedack=0
cbrreceived=0
cbrat=0
cbrdata=0
vbrreceived=0
vbrdata=0
cbrsimtime=0
vbrsimtime=0
}



{
if ($1 == "r" && $9 == "tcp" && $7==6){
tcpreceiveddata+=1
pkt_size = $11
recv += pkt_size-20
simtime=$3

}


if ($1 == "r" && $9 == "tcp" && $7==2){
tcpatdata+=1

}


if ($1 == "r" && $9 == "ack" && $7==5){
tcpack+=1


}

if ($1 == "r" && $9 == "ack" && $7==1){
tcpreceivedack+=1
acksize+=$11
}
if ($1 == "r" && $9 == "cbr" && $7==6){
cbrreceived+=1
cbrdata+=$11-8
if (cbrsimtime==0){cbrstarttime=$3
}
cbrsimtime=$3

}
if ($1 == "r" && $9 == "cbr" && $7==2){
cbrat+=1



}
if ($1 == "r" && $9 == "exp" && $7==6){
vbrreceived+=1
vbrdata+=$11-8
if (vbrsimtime==0){vbrstarttime=$3
}
vbrsimtime=$3
}
if ($1 == "r" && $9 == "exp" && $7==2){
vbrat+=1



}




}


END { printf ("Header sizes are ripped\n")
#printf("TCP simulation ends at %g\n", simtime)
printf("TCP attempted to send %g data packets but only %g of them arrived by the throughput : %g Kbps \n",tcpatdata, tcpreceiveddata, (recv/simtime)*(8/1000))
printf("TCP sent %g acks and %g of them were delivered. \n", tcpack, tcpreceivedack)
#printf("Actual time for CBR simulation to end: %g\n", cbrsimtime)
printf("CBR sent %g data packets and %g were delivered by the throughput: %g Kbps\n", cbrat, cbrreceived, (cbrdata/(cbrsimtime-cbrstarttime))*(8/1000))
#printf("Actual time for VBR simulation end: %g start:%g \n", vbrsimtime, vbrstarttime)
printf("VBR sent %g packets and %g were delivered by the throughput: %g Kbps\n", vbrat, vbrreceived, (vbrdata/(vbrsimtime-vbrstarttime))*(8/1000))
printf("System throughput is %g Kbps\n", ((recv+cbrdata+vbrdata)/simtime)*(8/1000))
}



go to ns2, awk -f tr.awk out.nam


this shows you throughput of your vbr, cbr and tcp average throughputs.







name for instant delayfile : insde.awk

BEGIN {
send[""]=50;
recv[""]=0;
received =0
settime=0
gr=0.1
arr=1

}

{
if (($1 == "+")&&($9 == "tcp")&&($5 == 1)){

send[$15]=$3


}

if (($1 == "r")&&($9 == "tcp")&&($7 == 6)){
received= received+1
recv[$15] = $3

average+= recv[$15]-send[$15]
if ($3 <= settime) {
arr=arr+1
subtotal=subtotal+recv[$15]-send[$15]

#printf ("eski arr:%g", arr)
}
else {
subtotal= subtotal/arr
print settime, subtotal > "insde.txt"
set=set+1
arr=1
settime=settime+gr
#printf ("yeni arr:%g", arr)
subtotal=recv[$15]-send[$15]
}

}




}


END { #average = average / received
#printf("Average delay is %g seconds with total %g received packets \n",average, received)
subtotal= subtotal/arr
print settime, subtotal > "insde.txt"

}

then awk -f insde.awk out.nam

to plot the instant delay over time, go to ns2 directory and write this command: gnuplot


This opens gnuplot interface.


here write plot "insde.txt" with lines


you will see the result now.


last phase: For instant throughput call this file insth.awk


BEGIN {settime=0
gr=0.1
subtotal=0
total=0
set=0
}

{
if (($1 == "r")&&($9 == "tcp")&&($7 == 6)){

if ($3 <= settime) {

subtotal=subtotal+$11
total=total+(subtotal/gr)*8/1000
set=set+1

}
else {
subtotal= (subtotal/gr)*8/1000
print settime, subtotal > "insth.txt"
set=set+1
total=total+subtotal
settime=settime+gr

subtotal=$11
}

}







}


END {
subtotal= (subtotal/gr)*8/1000
#printf ("total %g", total)

print settime, subtotal > "insth.txt"
print settime > "time.txt"


}



go to ns2 and enter: awk -f insth.awk out.nam


go to ns2 again, write gnuplot. gnuplot opens, then write plot "insth.txt" with lines



enjoy your life. greetings from Turkey.







No comments: