Suppose a TCP receiver receives 60 M Bytes of data in 1 min, then:
$ns trace-queue $src_node $dest_node $output_file |
This will instruct NS to write packet arriving activities on the link ($src_node, $dest_node) to the output file $output_file
set n0 [$ns node] set n1 [$ns node] $ns duplex-link $n0 $n1 2Mb 10ms DropTail set trace_file [open "out.tr" w] $ns trace-queue $n0 $n1 $trace_file |
|
+ 0.311227 3 4 tcp 592 ------- 0 0.0 4.0 0 0 - 0.311227 3 4 tcp 592 ------- 0 0.0 4.0 0 0 r 0.351867 3 4 tcp 592 ------- 0 0.0 4.0 0 0 |
|
|
#Make a NS simulator
set ns [new Simulator]
# Define a 'finish' procedure
proc finish {} {
exit 0
}
# Create the 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]
# Create the links:
$ns duplex-link $n0 $n2 2Mb 10ms DropTail
$ns duplex-link $n1 $n2 2Mb 10ms DropTail
$ns duplex-link $n2 $n3 0.3Mb 200ms DropTail
$ns duplex-link $n3 $n4 0.5Mb 40ms DropTail
$ns duplex-link $n3 $n5 0.5Mb 30ms DropTail
# Add a TCP sending module to node n0
set tcp1 [new Agent/TCP/Reno]
$ns attach-agent $n0 $tcp1
# Add a TCP receiving module to node n4
set sink1 [new Agent/TCPSink]
$ns attach-agent $n4 $sink1
# Direct traffic from "tcp1" to "sink1"
$ns connect $tcp1 $sink1
# Setup a FTP traffic generator on "tcp1"
set ftp1 [new Application/FTP]
$ftp1 attach-agent $tcp1
$ftp1 set type_ FTP (no necessary)
# Schedule start/stop times
$ns at 0.1 "$ftp1 start"
$ns at 100.0 "$ftp1 stop"
# Set simulation end time
$ns at 125.0 "finish" (Will invoke "exit 0")
##################################################
## Obtain Trace date at destination (n4)
##################################################
set trace_file [open "out.tr" w]
$ns trace-queue $n3 $n4 $trace_file
# Run simulation !!!!
$ns run
|
Run progran with NS and you will get a trace file
|
These are the packets that are received by TCP entity "4.0" in the first second:
|
The total number of bytes received in the first second is therefore:
or:
So the throughput in the first second is 9792 bits/sec = 0.009792 Mbps
Repeat the process for the second second, and so on...
You do NOT want to do that by hand...
Save it and run as using:
perl throughput.pl trfile destNode srcNode.port# destNode.port# \ time-granularity |
Time-granularity let you compute the throughput over time intervals, each interval will have the size given by the time-granularity
You can use the following command to get average throughput data from the trace file obtained in the NS script above:
perl throughput.pl out.tr 4 0.0 4.0 1 > out |
We need to use these parameters to extract the throughput data because of:
r 0.351867 3 4 tcp 592 ------- 0 0.0 4.0 0 0 |
To plot the progressing of average throughput, use gnuplot:
gnuplot >> plot "out" using 1:2 title "TCP throughput" with lines 1 |
|
Therefore, the throughput between 3 and 4 second is:
54 x 592 bytes = 31968 bytes /sec = 255744 bits/sec = 0.255744 Mbps |
Only packets with sequence numbers 32 to 49 (18 packets) are counted as "good" throughput.
Therefore, the goodput between 3 and 4 second is:
18 x 592 bytes = 10656 bytes/sec = 85248 bits/sec = 0.085248 Mbps |
|
 
  |
In the class TraceApp we need to write a method recv(x) - the parameter x is the number of bytes in the data segment.
// Define "TraceApp" as a child class of "Application"
Class TraceApp -superclass Application
// Define (override) "init" method to create "TraceApp" object
TraceApp instproc init {args} {
$self set bytes_ 0
eval $self next $args
}
// Define (override) "recv" method for "TraceApp" object
TraceApp instproc recv {byte} {
$self instvar bytes_
set bytes_ [expr $bytes_ + $byte]
return $bytes_
}
|
(You can view this method as the constructor)
The init{args} method set the variable bytes_ to 0 (this variable is used to tally the number of bytes received)
(In fact, the recv{byte} method is defined in the parent class Application - by defining a new recv{byte} method in the child class TraceApp, we have overridden the one in the parent class Application)
The most important statement in recv{byte} is:
set bytes_ [expr $bytes_ + $byte] |
NOTE:
|
You work with the TraceApp just the way you used
the Application/FTP
application.
So, to use TraceApp:
|
set sink1 [new Agent/TCPSink] ;# Create a TCPSink object set traceapp [new TraceApp] ;# Create a TraceApp object $traceapp attach-agent $sink1 ;# Attach traceapp to TCPSink $ns at 0.0 "$traceapp start" ;# Start the traceapp object |
plotThroughput {tcpSink outfile} {
global ns
set now [$ns now] ;# Read current time
set nbytes [$tcpSink set bytes_] ;# Read number of bytes
$tcpSink set bytes_ 0 ;# Reset for next epoch
### Prints "TIME throughput" to output file
set throughput [expr ($nbytes * 8.0 / 1000000) / $time_incr]
puts $outfile "$now $throughput"
set time_incr 1.0
$ns at [expr $now+1.0] "plotThroughput $tcpSink $outfile"
}
|
When you run the program, it will create an output file "out2.tput" that contain goodput data which you can plot using gnuplot: