Showing posts with label TCP. Show all posts
Showing posts with label TCP. Show all posts

Monday, November 5, 2012

NS-2 Simulation

Installing NS2 on Ubuntu 11.04
sudo apt-get install ns2 nam
Here I have used NS-2 to simulate a network with the topology as shown below.


I have written tcl scripts to create the above topology and to show,
  1. When two TCP flows compete for the bandwidth they fairly share the bandwidth
  2. When a TCP flow and a UDP flow compete for the bandwidth there is no fair sharing
Also I have plotted the throughput at the receivers against time using xgraph.

Installing xgraph on Ubuntu 11.04
sudo apt-get install xgraph
To start the simulation
ns XXX.tcl
How two TCP flows compete for the bandwidth

tcp_tcp.tcl

This script simulates two TCP flows; one between n0 and n4 and one between n1 and n5. Also the bandwidth of L2 has selected in such a way that it becomes the bottleneck link and the "record" procedure has used to measure the throughput at the receivers. .
#Create a simulator object
set ns [new Simulator]

#Define different colors for data flows (for NAM)
$ns color 1 Blue
$ns color 2 Red

#Open the trace files outX.tr for Xgraph and out.nam for nam
set f0 [open out_tcp0.tr w]
set f1 [open out_tcp1.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
 $ns flush-trace
#Close the NAM trace file
 close $nf
#Close the output files
 close $f0
 close $f1
#Execute xgraph to display the results
 exec xgraph out_tcp0.tr out_tcp1.tr -geometry 600x400 &
#Execute NAM on the trace file
 exec nam out.nam &
 exit 0
}

#Create five 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 links between the nodes
$ns duplex-link $n0 $n2 2Mb 10ms DropTail
$ns duplex-link $n1 $n2 2Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.7Mb 20ms DropTail
$ns duplex-link $n3 $n4 2Mb 10ms DropTail
$ns duplex-link $n3 $n5 2Mb 10ms DropTail

#Set Queue Size of link (n2-n3) to 20
$ns queue-limit $n2 $n3 20

#Give node position (for NAM)
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right
$ns duplex-link-op $n3 $n4 orient right-up
$ns duplex-link-op $n3 $n5 orient right-down

#record procedure
proc record {} {
 global sink 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.5

#How many bytes have been received by the traffic sinks?
 set bw0 [$sink 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
 $sink set bytes_ 0
 $sink1 set bytes_ 0

#Re-schedule the procedure
 $ns at [expr $now+$time] "record"
}

#Setup a TCP connection
set tcp [new Agent/TCP]
$tcp set class_ 2
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n4 $sink
$ns connect $tcp $sink
$tcp set fid_ 1

#Setup a FTP over TCP connection
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP

#Setup a TCP connection
set tcp1 [new Agent/TCP]
$tcp1 set class_ 2
$ns attach-agent $n1 $tcp1
set sink1 [new Agent/TCPSink]
$ns attach-agent $n5 $sink1
$ns connect $tcp1 $sink1
$tcp1 set fid_ 2

#Setup a FTP over TCP connection
set ftp1 [new Application/FTP]
$ftp1 attach-agent $tcp1
$ftp1 set type_ FTP

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

#Schedule events for the FTP agents
$ns at 0.1 "$ftp start"
$ns at 0.8 "$ftp1 start"
$ns at 4.0 "$ftp1 stop"
$ns at 4.8 "$ftp stop"

#Call the finish procedure after 5 seconds of simulation time
$ns at 5.0 "finish"

#Run the simulation
$ns run

Graph


Above graph visualization clearly shows how two TCP flows fairly share the bandwidth.

How a TCP flow and a UDP flow compete for the bandwidth

tcp_udp.tcl

This script simulates one TCP flow (between n0 and n4) and one UDP flow (between n1 and n5). Again the bandwidth of L2 has selected in such a way that it becomes the bottleneck link and the "record" procedure has used to measure the throughput at the receivers.
#Create a simulator object
set ns [new Simulator]

#Define different colors for data flows (for NAM)
$ns color 1 Blue
$ns color 2 Red

#Open the trace files outX.tr for Xgraph and out.nam for nam
set f0 [open out_tcp.tr w]
set f1 [open out_udp.tr w]

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

#Define a 'finish' procedure
proc finish {} {
 global ns nf f0 f1
 $ns flush-trace
#Close the NAM trace file
 close $nf
#Close the output files
 close $f0
 close $f1
#Execute xgraph to display the results
 exec xgraph out_tcp.tr out_udp.tr -geometry 600x400 &
#Execute NAM on the trace file
 exec nam out_udptcp.nam &
 exit 0
}

#Create five 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 links between the nodes
$ns duplex-link $n0 $n2 2Mb 10ms DropTail
$ns duplex-link $n1 $n2 2Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.7Mb 20ms DropTail
$ns duplex-link $n3 $n4 2Mb 10ms DropTail
$ns duplex-link $n3 $n5 2Mb 10ms DropTail

#Set Queue Size of link (n2-n3) to 20
$ns queue-limit $n2 $n3 20

#Give node position (for NAM)
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right
$ns duplex-link-op $n3 $n4 orient right-up
$ns duplex-link-op $n3 $n5 orient right-down

#record procedure
proc record {} {
 global sink 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.5

#How many bytes have been received by the traffic sinks?
 set bw0 [$sink 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
 $sink set bytes_ 0
 $sink1 set bytes_ 0

#Re-schedule the procedure
 $ns at [expr $now+$time] "record"
}

#Setup a TCP connection
set tcp [new Agent/TCP]
$tcp set class_ 2
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n4 $sink
$ns connect $tcp $sink
$tcp set fid_ 1

#Setup a FTP over TCP connection
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP

#Setup a UDP connection
set udp [new Agent/UDP]
$ns attach-agent $n1 $udp
set sink1 [new Agent/LossMonitor]
$ns attach-agent $n5 $sink1
$ns connect $udp $sink1
$udp set fid_ 2

#Setup a CBR over UDP connection
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 2mb
$cbr set random_ false

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

#Schedule events for the CBR and FTP agents
$ns at 0.1 "$cbr start"
$ns at 0.8 "$ftp start"
$ns at 4.0 "$ftp stop"
$ns at 4.8 "$cbr stop"

#Call the finish procedure after 5 seconds of simulation time
$ns at 5.0 "finish"

#Run the simulation
$ns run
Graph


Above graph visualization clearly shows, when it comes to a TCP flow and a UDP flow there is no fair sharing the bandwidth, UDP gets the most of it.

Thursday, December 2, 2010

Synchronous Client Server Application in C#

TCP Based Server

  • Establish the local end point for the socket
  • Open a socket using Socket()
  • Name the socket using Bind()
  • Listen for incoming connections using Listen(), parameter inside the method specifies the maximu number of pending connections
  • Accept client connections using Accept(), a new socket is created here but the original socket keeps listen
  • Send, Receive data using Send() and Receive()
  • Close Socket using Close()

Server.cs

   using System; 
   using System.Net.Sockets; 
   using System.Net; 
   using System.Text; 

   public class SocketServer 
   { 
      public static void Main(string [] args) 
      { 

         // establish the local end point for the socket 
         IPHostEntry ipHost = Dns.Resolve("localhost"); 
         IPAddress ipAddr = ipHost.AddressList[0]; 
         IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000); 

         // create a Tcp/Ip Socket 
         Socket sListener = new Socket(AddressFamily.InterNetwork, 
                                       SocketType.Stream, ProtocolType.Tcp); 

         // bind the socket to the local endpoint and 
         // listen to the incoming sockets 

         try 
         { 
            sListener.Bind(ipEndPoint); 
            sListener.Listen(10); 

            // Start listening for connections 

            while (true) 
            { 
               Console.WriteLine("Waiting for a connection on port {0}",ipEndPoint); 

               // program is suspended while waiting for an incoming connection 
               Socket handler = sListener.Accept(); 

               string data = null; 

               // we got the client attempting to connect 
               while(true) 
               { 
                  byte[] bytes = new byte[1024]; 

                  int bytesRec = handler.Receive(bytes); 

                  data += Encoding.ASCII.GetString(bytes, 0, bytesRec); 

                  if (data.IndexOf("<theend>") > -1) 
                  { 
                     break; 
                  } 
               } 

               // show the data on the console 
               Console.WriteLine("Text Received: {0}",data); 

               string theReply = "Thank you for those " + data.Length.ToString() 
                               + " characters..."; 
               byte[] msg = Encoding.ASCII.GetBytes(theReply); 

               handler.Send(msg); 
               handler.Shutdown(SocketShutdown.Both); 
               handler.Close(); 
            } 
         } 
         catch(Exception e) 
         { 
            Console.WriteLine(e.ToString()); 
         } 

      } // end of Main 
   } 



TCP Based Client

  • Establish a remote endpoint
  • Open a socket using Socket()
  • Connect to the remote host using Connect
  • Send, receive data using Send() and Receive()
  • Close Socket using Close()

Client.cs

using System; 
using Systern.Net.Sockets; 
using Systern.Net; 
using Systern.Text; 

public class SocketClient 
{ 
   public static void Main(string [] args) 
   {

    // data buffer for incoming data 
    byte[] bytes = new byte[1024]; 

    // connect to a Remote device 
    try 
    { 
       // Establish the remote end point for the socket 
       IPHostEntry ipHost = Dns.Resolve("127.0.0.1"); 
       IPAddress ipAddr = ipHost.AddressList[0]; 
       IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000); 

       Socket sender = new Socket(AddressFamily.Internetwork, 
                                  SocketType.Stream, ProtocolType.Tcp); 

       // Connect the socket to the remote endpoint 

          sender.Connect(ipEndPoint); 

          Console.WriteLine("Socket connected to {0}", 
          sender.RemoteEndPoint.ToString()); 

          string theMessage = "This is a test"; 

          byte[] msg = Encoding.ASCII.GetBytes(theMessage+"<theend>"); 

          // Send the data through the socket 
          int bytesSent = sender.Send(msg); 

          // Receive the response from the remote device 
          int bytesRec = sender.Receive(bytes); 

          Console.WriteLine("The Server says : {0}", 
                            Encoding.ASCII.GetString(bytes,0, bytesRec)); 

          // Release the socket 
          sender.Shutdown(SocketShutdown.Both); 
          sender.Close(); 

    } 
    catch(Exception e) 
    { 
       Console.WriteLine("Exception: {0}", e.ToString()); 
    } 
  } 
} 



Fllowing image shows how client and server send and receive data

TCP Fundamentals