• Alibek Jakupov

Comparing TCP and UDP : Learning by doing

Updated: May 1


Quote from Wikipedia

The Transmission Control Protocol (TCP) is one of the main protocols of the Internet protocol suite. It originated in the initial network implementation in which it complemented the Internet Protocol (IP). Therefore, the entire suite is commonly referred to as TCP/IP. TCP provides reliable, ordered, and error-checked delivery of a stream of octets (bytes) between applications running on hosts communicating via an IP network. Major internet applications such as the World Wide Web, email, remote administration, and file transfer rely on TCP. Applications that do not require reliable data stream service may use the User Datagram Protocol (UDP), which provides a connectionless datagram service that emphasizes reduced latency over reliability.

And another quote

In computer networking, the User Datagram Protocol (UDP) is one of the core members of the Internet protocol suite. The protocol was designed by David P. Reed in 1980 and formally defined in RFC 768. With UDP, computer applications can send messages, in this case referred to as datagrams, to other hosts on an Internet Protocol (IP) network. Prior communications are not required in order to set up communication channels or data paths. In computer networking, the User Datagram Protocol (UDP) is one of the core members of the Internet protocol suite. The protocol was designed by David P. Reed in 1980 and formally defined in RFC 768. With UDP, computer applications can send messages, in this case referred to as datagrams, to other hosts on an Internet Protocol (IP) network. Prior communications are not required in order to set up communication channels or data paths.

The goal of this short article is to explain how to set up your experiment up and running and to see the difference between tcp and udp protocols by yourself. A reader should already have a basic understanding of communication and difference between TCP and UDP protocols. For any theoretical references you may use Wikipedia articles (see above), which are well documented. Up we go!



Step 1 : UDP


First we need to write a simple datagram client/server in Java. The client should set a timer, then send a one-byte packet to the server and wait for the server to echo the packet back. This send-and-echo should be repeated 1000 times. We will then stop the timer and measure the average round trip time to send a UDP packet containing one byte of data. As UDP is not reliable we will have to set a time-out for receiving.


Here's our UDP server

import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.SocketException;



public class DatagramServer {
 private final static int PORT_NUMBER = 8000;
 
 private static byte[] receive;
 private static DatagramSocket serverDatagram;
 private static DatagramPacket receiveDatagramPacket;
 private static DatagramPacket sendDatagramPacket;
 
 public static void main(String[] args) throws SocketException {
        receive = new byte[1];
        serverDatagram = new DatagramSocket(PORT_NUMBER);
 
        System.out.println("Welcome to datagram server");
 while (true) {
            receiveDatagramPacket = new DatagramPacket(receive, 1);
            System.out.println("The packet has " + 
 "been successfully created");
 try {
                serverDatagram.receive(receiveDatagramPacket);
                System.out.println("Packet transmission...");
                System.out.println(receiveDatagramPacket.getPort());
 
 InetAddress destIP = receiveDatagramPacket.getAddress();
 int destPort = receiveDatagramPacket.getPort();
 
                sendDatagramPacket = new DatagramPacket(
                    receiveDatagramPacket.getData(), 1, destIP, destPort);
 
                    serverDatagram.send(sendDatagramPacket);
                } catch (IOException e) {
                    System.out.println("Error, while creating packet");
                    e.printStackTrace();
                }
                serverDatagram.close();
            }
    }
}

And, of course our UDP client

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;



public class DatagramClient {
 private static final int PORT_NUMBER = 8001;
 private static final String HOST = "localhost";
 private static DatagramSocket clientDatagram;
 private static byte[] send;
 private static byte[] receive;
 private static long sendTime = 0;
 private static long receiveTime = 0;
 private static long RTT = 0;
 private static long RTTSum = 0;
 private static DatagramPacket sendPacket;
 private static DatagramPacket receivePacket;
 
 public static void main (String[] args) throws IOException {
        send = new byte[1];
        receive = new byte[1];
 String test = "a";
        send = test.getBytes();
 
 InetAddress destIP = InetAddress.getByName(HOST);
 
        clientDatagram = new DatagramSocket(PORT_NUMBER);
        System.out.println("The client datagram is running");
 
        clientDatagram.setSoTimeout(100);
 
 for (int i = 0; i < 100; i++) {
            sendPacket = new DatagramPacket(send, 1, destIP, PORT_NUMBER);
 
            System.out.println("Sending packets..." + i);
            clientDatagram.send(sendPacket);
 //record the send time
            sendTime = System.currentTimeMillis();
 
 //now we receive the packet
            receivePacket = new DatagramPacket(receive, 1);
            clientDatagram.receive(receivePacket);
 
            System.out.println("Receiving packets...");
 
 //record the receive time
            receiveTime = System.currentTimeMillis();
            RTT = receiveTime - sendTime;
 
            System.out.println("RTT is " + RTT);
            RTTSum += RTT;
 
 if (sendPacket.getData().equals(receivePacket.getData())) {
                System.out.println("Everything is alright");
            } else {
                i = i-1;
                System.out.println("Packet loss");
            }
        }
 
        System.out.println("The average RoundTripTime is: " + RTTSum/1000);
        clientDatagram.close();
    }
}


Step 2 : TCP

Here we will write a TCP counterpart to the above section. Again, we will set a timer, and measure how long it takes to set up 1000 connections. As before, measure the average round trip time to send one byte. We should also create a new socket for each byte and to close the socket once the byte has been sent and the reply received.

TCP Server

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class TCPServer {
 private final static int PORT_NUMBER = 8000;
 private final static int BUFFER_SIZE = 8192;
 
 private static BufferedInputStream istream;
 private static BufferedOutputStream ostream;
 private static byte[] buffer;
 private static ServerSocket serverSocket;
 private static Socket socket;
 
 public static void main(String[] args) throws IOException {
        serverSocket  = new ServerSocket(PORT_NUMBER);
 
        System.out.println("Welcome");
 
 while (true) {
            socket = serverSocket.accept();
            System.out.println("Connection is created");
 
            istream = new BufferedInputStream(
                socket.getInputStream());
            ostream = new BufferedOutputStream(
                socket.getOutputStream());
 
            buffer = new byte[BUFFER_SIZE];
 
            istream.read(buffer, 0, 1);
 
            System.out.println("Byte accepted");
 
            ostream.write(buffer, 0, 1);
 
            System.out.println("Byte is sent");
 
            istream.close();
            ostream.flush();
            socket.close();
        }
    }
}

TCP Client

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;


import javax.net.ssl.HostnameVerifier;



public class TCPClient {
 private final static int PORT_NUMBER = 8000;
 private final static String HOSTNAME = "localhost";
 
 private static BufferedInputStream istream;
 private static BufferedOutputStream ostream;
 private static Socket socket;
 
 private static long sendTime = 0;
 private static long receiveTime = 0;
 private static long RTT;
 private static long RTTSum;
 
 private static byte[] receive;
 
 public static void main(String[] args) throws UnknownHostException, IOException {
        receive = new byte[1];
 
 for (int i= 0; i < 1000; i++) {
            socket = new Socket (HOSTNAME, PORT_NUMBER);
            istream = new BufferedInputStream(socket.getInputStream());
            ostream = new BufferedOutputStream(socket.getOutputStream());
 
 String test = "a";
 //record the send time
            sendTime = System.currentTimeMillis();
 
            ostream.write(test.getBytes(), 0, 1);
 
            System.out.println("Sending bytes");
 
            istream.read(receive);
 //record the receive time
            receiveTime = System.currentTimeMillis();
 
            System.out.println("Receiving bytes");
 
            RTT = receiveTime - sendTime;
 
            System.out.println("The RTT is: " + RTT);
 
            RTTSum += RTT;
 
            socket.close();
        }
    }
}


So how do we set the experiment up?


You need first to run the client on a machine. You then run your server on another machine.


Important: your machines should in the same network.

Hint: to get your server machine's ip run the following command:


ipconfig

and look for your network card (e.g. WiFi). We need only IPv4.


Finally, we will measure the UDP and TCP round trip times. It may also be interesting to measure the round trip time using Ping.


Now, we should be able to answer the following questions:


How many packets should it take to send one byte over UDP?


How many packets does it take to establish a TCP connection, send one byte, and close the connection?


TCP – 8 packets, because in TCP there are so-called handshakes to verify the connection

  • 3 packets to establish connection

  • 1 packet – Send SYN

  • 1 packet receive SYN

  • 1 packet send ACK

  • 2 packets to send one byte

  • 3 packets to close connection


UDP =1 packet

As according to the UDP documentation the application does not verify the connection reliability, thus less packets are sent.


In this little practical assessment we tried to simulate a traffic over a small network and dip our toe in the water. Hope this article will encourage you to discover the fascinating world of network and communication.

©2018 by macnabbs. Proudly created with Wix.com