Queuing Models in NS2

M/M/1 is a system with poisson arrival time, servicing exponentially and a queue of unlimited capacity and type of FIFO Queue. This is the simplest queuing system.  NS2 supports various distributions like pareto, exponential, constant, unifrom, etc to handle the network dynamics and metrics.
So it is very easy to test the given network link to monitor a given queue using any of these queuing models. The listing 3 and 4 are monitoring the link when DropTail queue is used with a capacity of finite and infinite.
Listing 13.3 uses infinite capacity and Listing 13.4 uses Finite capacity The output screen shot is shown below the scripts for further understanding

Listing 3 – M/M/1 Queuing Model
#new Simulator creation
set ns [new Simulator]
#trace file creation for capturing the UDP data
set tf [open out.tr w]
$ns trace-all $tf

#setting the exponential distribution param
set lambda 30.0
set mu     33.0

#creation of nodes
set n1 [$ns node]
set n2 [$ns node]
#The queue limit is 1Lakh as the capacity is infinite. Simulation will take # more time when the limit is increased.
set link [$ns simplex-link $n1 $n2 100kb 0ms DropTail]
$ns queue-limit $n1 $n2 100000

# generate random interarrival times and packet sizes
set InterArrivalTime [new RandomVariable/Exponential]
$InterArrivalTime set avg_ [expr 1/$lambda]
set pktSize [new RandomVariable/Exponential]
$pktSize set avg_ [expr 100000.0/(8*$mu)]

#create new agent UDP
set src [new Agent/UDP]
$ns attach-agent $n1 $src

# queue monitoring and send the output to queue.out file
set qmon [$ns monitor-queue $n1 $n2 [open queue.out w] 0.1]
$link queue-sample-timeout

proc finish {} {
    global ns tf
    $ns flush-trace
    close $tf
    exit 0
}

proc sendpacket {} {
    global ns src InterArrivalTime pktSize
    set time [$ns now]
    $ns at [expr $time + [$InterArrivalTime value]] "sendpacket"
    set bytes [expr round ([$pktSize value])]
    $src send $bytes
}

set sink [new Agent/Null]
$ns attach-agent $n2 $sink
$ns connect $src $sink
$ns at 0.0001 "sendpacket"
$ns at 1000.0 "finish"

$ns run
To see the output of the above script, execute the following in the terminal
Prompt] gawk '{ print $1, $4, $5, $6, $7, $8, $9, $10, $11 }' queue.out > qm.pre
Prompt] xgraph qm.pre -geometry 500x500 -t “MM1 Queuing Example”
Here is the output screen
Queuing models in ns2
Queuing models in ns2


In the above Listing 13.3, large buffers are used to avoid losses. One can use smaller buffers and observe losses. The way to compute the loss probability from the simulation is simply to divide the total number of losses by the total number of arrivals, both given in the last line of the monitor-queue file. The command
$src set packetSize_ 100000
may be added.
The loss may be computed using the formula
P = pow(p,k)/Pow(p,i);


Listing 4 – M/M/1 with Finite capacity
#create new simulator
set ns [new Simulator]
#open the trace file for capturing UDP
set tf [open out.tr w]
$ns trace-all $tf

#setting the parameters for Exponential distribution
set lambda   30.0
set mu       33.0
set qsize     2
set duration  2000

#creation of new nodes
set n1 [$ns node]
set n2 [$ns node]
#creation of link with queue
set link [$ns simplex-link $n1 $n2 100kb 0ms DropTail]
#setting the queue size as 2
$ns queue-limit $n1 $n2 $qsize

# generate random interarrival times and packet sizes
set InterArrivalTime [new RandomVariable/Exponential]
$InterArrivalTime set avg_ [expr 1/$lambda]
set pktSize [new RandomVariable/Exponential]
$pktSize set avg_ [expr 100000.0/(8*$mu)]

#creation of new UDP Agent
set src [new Agent/UDP]
$src set packetSize_ 100000
$ns attach-agent $n1 $src

#queue monitoring
set qmon [$ns monitor-queue $n1 $n2 [open queue1.out w] 0.1]
$link queue-sample-timeout

proc finish {} {
    global ns tf
    $ns flush-trace
    close $tf
    exit 0
}

proc sendpacket {} {
    global ns src InterArrivalTime pktSize
    set time [$ns now]
    $ns at [expr $time + [$InterArrivalTime value]] "sendpacket"
    set bytes [expr round ([$pktSize value])]
    $src send $bytes
}

set sink [new Agent/Null]
$ns attach-agent $n2 $sink
$ns connect $src $sink
$ns at 0.0001 "sendpacket"
$ns at $duration "finish"

$ns run
To see the output of the above script, execute the following in the terminal
Prompt] gawk '{ print $1, $4, $5, $6, $7, $8, $9, $10, $11 }' queue1.out > qm1.pre
Prompt] xgraph qm1.pre -geometry 500x500 -t “MM1 Queuing Example”
Here is the output screen
 
Queuing models in ns2
Queuing models in ns2

T S Pradeep Kumar

Random Number Generation using ns2

Random variables is an important concept in networks as the modeling of network traffic and other packet arrival times are mostly random models. Hence there is a necessity of modeling such metrics in ns2. NS2 supports various random models using different seed generations.

Seeds are numbers that are helpful in generating the random numbers. The seed number 0 indicates that the random number order changes every time the simulation is running. But other than 0, the order in which the random number generated are same.


The following listing 1 shows the random number generation for various distributions. This listing will just tell you how to create random number generation for various distributions. For seeing the output, refer to listing 2

Listing 1 – Random Number Generation Sample
#create the random number generation using RNG
set rand1 [new RNG]
set rand2 [new RNG]
set rand3 [new RNG]
#$repli is the value set already and it can be either 1 or <1 or >1
for {set i 1} {$i < $repli} {incr i} {
$rand1 next-substream;
$rand2 next-substream;
$rand3 next-substream;
}

Here are the distributions
Pareto Distribution
set r1 [new RandomVariable/Pareto]
$r1 use-rng $rand1
$r1 set avg_ 10.0
$r1 set shape_ 1.2

Constant – Specifies the constant number
set r2 [new RandomVariable/Constant]
$r2 use-rng $rand2
$r2 set val_ 5.0

Uniform distribution – Specifies the min and max number
set r3 [new RandomVariable/Uniform]
$r3 use-rng $rand3
$r3 set min_ 0.0
$r3 set max_ 10.0

Exponential distribution.- Specified the average value:
set r4 [new RandomVariable/Exponential]
$r4 use-rng $rand1
$r4 set avg_ 5

Hyperexponential distribution
set r5 [new RandomVariable/HyperExponential]
$r5 use-rng $rand2
$r5 set avg_ 1.0
$r5 set cov_ 4.0


The following listing 2 creates the random number generation for two different distributions uniform and exponential. The replication number is supplied through the command line option. If no replication number is supplied, it will be taken as 0 and it a value less than 1 is supplied then, it will be running with value 1. So the following example uses the replication number as 0, 1 or any higher number > 1 and it uses a seed value of 9999
The syntax for setting the seed value is

$defaultRNG seed N

Where N is a interger which may take 0 or 1 or any positive number

Listing 2 – Random number generation – Case 1
#filename : randtest1.tcl
#
# Usage: ns randtest.tcl [replication number]
#

if {$argc > 1} {
    puts "Usage: ns randtest1.tcl \[replication number\]"
    exit
}
set run 1
if {$argc == 1} {
    set run [lindex $argv 0]
}
if {$run < 1} {
    set run 1
}

# seed the default RNG
global defaultRNG
$defaultRNG seed 9999

# create the RNGs and set them to the correct substream
set arrivaldist [new RNG]
set size [new RNG]
for {set j 1} {$j < $run} {incr j} {
    $arrivaldist next-substream
    $size next-substream
}

# arrival_ is a exponential random variable describing the time between
# consecutive packet arrivals
set arrival_ [new RandomVariable/Exponential]
$arrival_ set avg_ 5
$arrival_ use-rng $arrivaldist

# size_ is a uniform random variable describing packet sizes
set size_ [new RandomVariable/Uniform]
$size_ set min_ 100
$size_ set max_ 5000
$size_ use-rng $size

# print the first 5 arrival times and sizes
for {set j 0} {$j < 5} {incr j} {
    puts [format "%-8.3f  %-4d" [$arrival_ value] \
            [expr round([$size_ value])]]
}
Here is the sample output for above file
Prompt] ~/ns-allinone-2.35/ns-2.35/tcl/ex $ ns randtest1.tcl 0
6.358     4783
5.828     1732
1.469     2188
0.732     3076
4.002     626
Prompt]~/ns-allinone-2.35/ns-2.35/tcl/ex $ ns randtest1.tcl 1
6.358     4783
5.828     1732
1.469     2188
0.732     3076
4.002     626
Prompt]~/ns-allinone-2.35/ns-2.35/tcl/ex $ ns randtest1.tcl 2
2.091     153
12.085    4732
3.588     2329
1.201     230
5.161     2980
Prompt]~/ns-allinone-2.35/ns-2.35/tcl/ex $ ns randtest1.tcl 3
2.515     1119
3.154     3118
9.673     1201
13.346    2515
7.052     2115
Prompt]~/ns-allinone-2.35/ns-2.35/tcl/ex $ ns randtest1.tcl 100
8.940     2149
0.888     4870
0.998     4860
1.801     1205
18.224    2534
Prompt]~/ns-allinone-2.35/ns-2.35/tcl/ex $ ns randtest1.tcl 0.5
6.358     4783
5.828     1732
1.469     2188
0.732     3076
4.002     626



Multicasting in NS2

Mutlicast routing in ns2 can be easily set using any of the following syntax

Method 1:
        set ns [new Simulator -multicast on]
Method 2:
        set ns [new Simulator]
        $ns multicast
when multicast mode is enabled, the nodes behave differently with the additional classifiers are created. A distribution tree kind of structure is created in the simulation when dealing with multicast routing.  NS supports three types of multicast routing: Centralized Multicast Routing(CM), Dense Mode (DM), Shared Tree Mode (ST) and Bi directional Shared Tree Support (BST).
Here is the method to specify the multicast routing in ns.
set cmc [$ns mrtproto CtrMcast]    # specify centralized multicast for all nodes;
# cmc is the handle for multicast protocol object;
$ns mrtproto DM                   # specify dense mode multicast for all nodes;
$ns mrtproto ST                  # specify shared tree mode to run on all nodes;

The agents in the protocol can be joining the group or leaving the group for multicasting. Two procedures are used join-group[] and leave-group[].
An example of a relatively simple multicast configuration is:
set ns [new Simulator -multicast on]; # enable multicast routing;
set group [Node allocaddr]  ; # allocate a multicast address;
set node0 [$ns node]         ;# create multicast capable nodes;
set node1 [$ns node]
$ns duplex-link $node0 $node1 1.5Mb 10ms DropTail

set tracef [open dm.tr w]
$ns trace-all $tracef

set namtracef [open dm.nam w]
$ns namtrace-all $namtracef

set mproto DM         ; # configure multicast protocol;
set mrthandle [$ns mrtproto $mproto]; # all nodes will contain multicast protocol agents;

set udp [new Agent/UDP]         ;# create a source agent at node 0;
$ns attach-agent $node0 $udp
set cbr [new Application/Traffic/CBR]       
$cbr attach-agent $udp
$udp set dst_addr_ $group
$udp set dst_port_ 0

set receiver [new Agent/LossMonitor];  # create a receiver agent at node 1;
$ns attach-agent $node1 $receiver
$ns at 0.3 "$node1 join-group $receiver $group"
$ns at 0.1 "$cbr start"

$ns at 5.0 "finish"

proc finish {} {
       global ns tracef namtracef
       exec nam dm.nam &
       close $tracef
       close $namtracef
       exit 0
}
$ns run
Sample Output :
The status bar shows that the node1 joins the group
Multicasting
Multicasting in Wired Networks 

There was no packet exchange which is discussed in the next topic
      


Centralized Multicast routing in ns2
#This example is to demonstrate the multicast routing protocol.
set ns [new Simulator -multicast on]
#Turn on Tracing
set tf [open output.tr w]
$ns trace-all $tf

# Turn on nam Tracing
set fd [open mcast.nam w]
$ns namtrace-all $fd

# Create 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]
set n7 [$ns node]

# Create links with DropTail Queues
$ns duplex-link $n0 $n2 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n2 1.5Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.5Mb 10ms DropTail
$ns duplex-link $n3 $n4 1.5Mb 10ms DropTail
$ns duplex-link $n3 $n7 1.5Mb 10ms DropTail
$ns duplex-link $n4 $n5 1.5Mb 10ms DropTail
$ns duplex-link $n4 $n6 1.5Mb 10ms DropTail

# Routing protocol: say distance vector
#Protocols: CtrMcast, DM, ST, BST
#Dense Mode protocol is supported in this example
set mproto DM
set mrthandle [$ns mrtproto $mproto {}]

# Set two groups with group addresses
set group1 [Node allocaddr]
set group2 [Node allocaddr]

# UDP Transport agent for the traffic source for group1
set udp0 [new Agent/UDP]
$ns attach-agent $n0 $udp0
$udp0 set dst_addr_ $group1
$udp0 set dst_port_ 0
set cbr1 [new Application/Traffic/CBR]
$cbr1 attach-agent $udp0

# Transport agent for the traffic source for group2
set udp1 [new Agent/UDP]
$ns attach-agent $n1 $udp1
$udp1 set dst_addr_ $group2
$udp1 set dst_port_ 0
set cbr2 [new Application/Traffic/CBR]
$cbr2 attach-agent $udp1

# Create receiver to accept the packets
set rcvr1 [new Agent/Null]
$ns attach-agent $n5 $rcvr1
$ns at 1.0 "$n5 join-group $rcvr1 $group1"
set rcvr2 [new Agent/Null]
$ns attach-agent $n6 $rcvr2
$ns at 1.5 "$n6 join-group $rcvr2 $group1"


set rcvr3 [new Agent/Null]
$ns attach-agent $n7 $rcvr3
$ns at 2.0 "$n7 join-group $rcvr3 $group1"

set rcvr4 [new Agent/Null]
$ns attach-agent $n5 $rcvr1
$ns at 2.5 "$n5 join-group $rcvr4 $group2"

set rcvr5 [new Agent/Null]
$ns attach-agent $n6 $rcvr2
$ns at 3.0 "$n6 join-group $rcvr5 $group2"

set rcvr6 [new Agent/Null]
$ns attach-agent $n7 $rcvr3

#The nodes are leaving the group at specified times
$ns at 3.5 "$n7 join-group $rcvr6 $group2"
$ns at 4.0 "$n5 leave-group $rcvr1 $group1"
$ns at 4.5 "$n6 leave-group $rcvr2 $group1"
$ns at 5.0 "$n7 leave-group $rcvr3 $group1"
$ns at 5.5 "$n5 leave-group $rcvr4 $group2"
$ns at 6.0 "$n6 leave-group $rcvr5 $group2"
$ns at 6.5 "$n7 leave-group $rcvr6 $group2"

# Schedule events

$ns at 0.5 "$cbr1 start"
$ns at 9.5 "$cbr1 stop"
$ns at 0.5 "$cbr2 start"
$ns at 9.5 "$cbr2 stop"

#post-processing

$ns at 10.0 "finish"
proc finish {} {
  global ns tf
   $ns flush-trace
   close $tf
   exec nam mcast.nam &
   exit 0
}

$ns set-animation-rate 3.0ms
$ns run
Sample Output Screenshots
Multicasting
Multicasting  in Wired Networks

The nodes are joining the group before the packet transfer and leaving the group at a specified time.
Multicasting
Multicasting  in Wired Networks



                                                                 

Error "bailing in Tcl::eval"

In ns2, if you ever encounter a error like "bailing in Tcl::eval", then it could be due the size of the buffer that Tcl:: eval may offer
By default the buffer size is 1024 and it can be increased to 2048 (for example)

Usually this error will be encountered when you increase the number of nodes in the simulation (for example more than 100 nodes might give you this error)

bailing in Tcl::eval
bailing in Tcl::eval
How to overcome this error? Here is a small workaround
Open the command prompt and go the ns-allinone-2.35/tclcl-1.xx/ folder and open the file Tcl.cc

$] cd ns-allinone-2.35/tclcl-1.20/Tcl.cc (in my case)

in the following function (Line number: 202, change 1024 to 2048) as shown below

void Tcl::eval()
{
char* p = bp_;
bp_ = p + strlen(p) + 1;
/*XXX*/
if (bp_ >= &buffer_[2048]) {
fprintf(stderr, "bailing in Tcl::eval\n");
assert(0);
exit(1);
}
eval(p);
bp_ = p;
}

Once the changes are made, reinstall ns2 itself

$] cd ns-allinone-2.35/
$] ./install 

T S Pradeep Kumar