Socket Programming with TCP/UDP

Socket Programming with TCP/UDP

Sockets

For every end system to get connect with other end systems, we need sockets. Sockets are nothing but a gateway for packets to flow between nodes(end systems).

Let's consider a scenario of network applications. The network application consists of a pair of programs - client program and a server program present in different end systems. On the execution of these programs, processes are created. These processes communicate via sockets.

Types of network applications

There are two types of network applications. One whose implementations is written in an RFC(A Request for Comments is a formal document check more details here.) In this both client and server side network applications will follow the rules of RFC and they are able to communicate for example - browser communicating with web server. The other type of network application is a exclusive network application.

TCP/UPD

Before jumping into socket programming with TCP/UPD and which one to use when. Let's dive into TCP and UPD protocols. TCP is connection oriented protocol and provides a reliable byte-stream channel through which data flows between end system. UPD is connectionless and sends independent packets of data from end system to the other, without any guarantees about the delivery.

Sockets with TCP:

TCP is connection oriented, this means that before the client and server starts sending data packets they first need to do handshake and establish a TCP connection. Both client and servers have their own sockets. Both the sockets are intact with the IP address and port numbers. When both sides want to communicate they drop data into the TCP connection via its socket.

Its always clients responsibility to initiate contact with the server. This means the TCP server must be running a process before the client attempts to initiate and the server program must have a door a special socket. While the server process is running, the client process an initiate a TCP connection. This is done in client program by creating TCP socket. When TCP socket it created by client, it specifies the IP address and port number of the welcoming socket in the server.A three-way handshake takes place int transport layer which is completely invisible to client and the client process tries to connect to the welcoming door. The sever listens and creates a new socket for the client.

Let's try doing some programming for a scenario with TCP:

  • Client reads a line of characters.

  • The server receives the data and convers the characters to uppercase

  • The server sends the modified data to the client.

  • The client receives the modified data and displays the line on its screen.

// TCPClient.java
import java.io.*;
import java.net.*;
class TCPClient {
    public static void main(String argv[]) throws Exception {
        String sentence;
        String modifiedSentence;

        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
        Socket clientSocket = new Socket(“hostname”, 6789);
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(

        clientSocket.getInputStream()));
        sentence = inFromUser.readLine();

        outToServer.writeBytes(sentence + ‘\n’);
        modifiedSentence = inFromServer.readLine();

        System.out.println(“FROM SERVER: “ + modifiedSentence);
        clientSocket.close();
    }
}
// TCPServer.java
import java.io.*;
import java.net.*;
class TCPServer {
    public static void main(String argv[]) throws Exception {
        String clientSentence;
        String capitalizedSentence;
        ServerSocket welcomeSocket = new ServerSocket(6789);
        while(true) {
            Socket connectionSocket = welcomeSocket.accept();
            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());

            clientSentence = inFromClient.readLine();
            capitalizedSentence = clientSentence.toUpperCase() + ‘\n’;
            outToClient.writeBytes(capitalizedSentence);        
        }
    }
}

Sockets with UDP

Let's see how communication happens between two processes that use UPD sockets. Before the client process starts sending data to the server process, the client process should first attach destination address to route the packet through the sender's socket, the Internet will user this packet to route it through and make it to the socket of server process. When the packet arrives at the server socket , the server process inspect the packet's contents and make decisions.

So now the question is what goes into the destination address that is attached to the packet how the routers will be able to route the packet through the Internet to the destination host? The packet has the destination IP address, also a host may be running many network application processes with one or multiple sockets so a post number is assigned to them as an identifier. So its essential for the client process to add destination's port number as well to the packet which is sent. In addition to this source's address is also added but not by UDP application but by operating system itself.

Here's how the program seems for UDP

// UDPClient.java
import java.io.*;
import java.net.*;
class UDPClient {
public static void main(String args[]) throws Exception {
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
        DatagramSocket clientSocket = new DatagramSocket();
        InetAddress IPAddress = InetAddress.getByName(“hostname”);
        byte[] sendData = new byte[1024];

        String sentence = inFromUser.readLine();
        sendData = sentence.getBytes();

        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
        IPAddress, 9876);
        clientSocket.send(sendPacket);

        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        clientSocket.receive(receivePacket);

        String modifiedSentence = new String(receivePacket.getData());
        System.out.println(“FROM SERVER:” + modifiedSentence);

        clientSocket.close();
    }
}
// UDPServer.java
import java.io.*;
import java.net.*;
class UDPServer {
public static void main(String args[]) throws Exception {
        DatagramSocket serverSocket = new DatagramSocket(9876);
        byte[] receiveData = new byte[1024];
        byte[] sendData = new byte[1024];

        while(true) {
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receivePacket);
            String sentence = new String(receivePacket.getData());
            InetAddress IPAddress = receivePacket.getAddress();

            int port = receivePacket.getPort();
            String capitalizedSentence = sentence.toUpperCase();

            sendData = capitalizedSentence.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
            serverSocket.send(sendPacket);
        }
    }
}

That completes our analysis of the UDP program pair. To test the application, you install and compile UDPClient.java in one host and UDPServer.java in another host. (Be sure to include the proper hostname of the server in UDP Client.java.) Then execute the two programs on their respective hosts. Unlike with TCP, you can first execute the client side and then the server side. This is because the client process does not attempt to initiate a connection with the server when you execute the client program. Once you have executed the client and server programs, you may use the application by typing a line at the client.