Interview Questions

Java - Socket Programming - Transmission Control Protocol (TCP)

In this article lets discuss about socket programming using java.

What is a Socket?

A socket is an endpoint for communication between two different machines. An application program can send/receive messages from a socket. Each socket has a port associated with it.

Socket Programming in java is used for inter process communication between two processes (programs) running in two different machines. There are two basic protocols can be used to transmitting the message.

1.) TCP/IP - Connection-Oriented Protocol
2.) UDP - Connection-less Protocol (You need to send the sender address for every packet transmitted).

Let’s consider a simple client-server model program to demonstrate the socket programming in java.

Consider the TCPServer.java class below. It does the following job.

1.) It creates an instance to Server Socket class with the given port number.
2.) The server Socket waits for a connection from a connection and accepts it when it receives one.
3.) Now it gets the input stream from Client Socket to receive the data from client.
4.) It processes the received data from client and returns back the response to the client.

The below program is self explanatory with necessary comments.

TCPServer.java

/**
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE IS DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package in.techdive.tcp.server;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * TCP Server Socket Implementation
 */

public class TCPServer
{
        public static void main(String[] args) throws Exception
        {
                DataInputStream is;
                DataOutputStream os;
                int port = 11111;
                ServerSocket serverSocket = new ServerSocket(port);

                System.out.println("Server Socket is Running...");
                System.out.println("Server is waiting for Connections");

                Socket clientSocket = serverSocket.accept();

                is = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));
                os = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));

                // Running continuously in-order to process Client Request
                while (true)
                {
                        // Fetches the Client request
                        byte[] byteData = receiveData(is);
                        String clientRequestMessage = new String(byteData).trim();
                        System.out.println("Received Message = " + clientRequestMessage);

                        // Processing Client request
                        String clientData = doProcess(clientRequestMessage);

                        // Sending Response to Client
                        sendData(os, clientData.getBytes());
                        System.out.println("Response Message sent to Client = " + clientData);
                }
        }

        /**
         * Add you Custom Business Logic here
         *
         * @param message
         *            Client Request Message
         * @return Server Response Message
         */

        public static String doProcess(String message)
        {
                System.out.println("Processing the Client Request...");
                if (message.equals("CLIENT_REQUEST:SEND_SYSTEM_TIME"))
                {
                        Date date = new Date(System.currentTimeMillis());
                        return date.toString();
                }
                else
                {
                        return "SERVER-ERROR:INVALID_REQUEST";
                }
        }

        /**
         * Method receives the Client Request
         */

        public static byte[] receiveData(DataInputStream is) throws Exception
        {
                try
                {
                        byte[] inputData = new byte[1024];
                        is.read(inputData);
                        return inputData;
                }
                catch (Exception exception)
                {
                        throw exception;
                }
        }

        /**
         * Method used to Send Response to Client
         */

        public static synchronized void sendData(DataOutputStream os, byte[] byteData)
        {
                if (byteData == null)
                {
                        return;
                }
                try
                {
                        os.write(byteData);
                        os.flush();
                }
                catch (Exception exception)
                {
                }
        }
}

Ok! We have the server ready to accept connections from client. Here is the client code TCPClient.java to connect and send data to the server.

TCPClient.java

/**
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package in.techdive.tcp.client;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

/**
 * TCP Socket Implementation
 */

public class TCPClient
{

        public static void main(String[] args) throws Exception
        {
                System.out.println("Client Started...");

                Socket socket = new Socket("localhost", 11111);
                DataInputStream is = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
                DataOutputStream os = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));

                // Create Client Request
                String request = "CLIENT_REQUEST:SEND_SYSTEM_TIME";

                // Send Client Request to Server
                send(os, request.getBytes());
                System.out.println("Data sent to Server ; Message = " + request);

                try
                {
                        while (true)
                        {
                                // Receive Server Response
                                byte[] byteData = receive(is);
                                String responseData = new String(byteData);
                                System.out.println("Server Response = " + responseData.trim());
                        }
                }
                catch (Exception e)
                {
                        System.out.println("Exception: " + e.getMessage());
                }
        }

        /**
         * Method receives the Server Response
         */

        public static byte[] receive(DataInputStream is) throws Exception
        {
                try
                {
                        byte[] inputData = new byte[1024];
                        is.read(inputData);
                        return inputData;
                }
                catch (Exception exception)
                {
                        throw exception;
                }
        }

        /**
         * Method used to Send Request to Server
         */

        public static void send(DataOutputStream os, byte[] byteData) throws Exception
        {
                try
                {
                        os.write(byteData);
                        os.flush();
                }
                catch (Exception exception)
                {
                        throw exception;
                }
        }
}

Here is the sample output for both client and server. Run the TCPServer.java and the output will be as follows

Server Socket is Running...
Server is waiting for Connections

Now execute the TCPClient.java and the output will be as follows

Client Started...
Data sent to Server ; Message = CLIENT_REQUEST:SEND_SYSTEM_TIME
Server Response = Sat Sep 25 15:08:28 IST 2010
 

Final output for the server program is

Received Message = CLIENT_REQUEST:SEND_SYSTEM_TIME
Processing the Client Request...
Response Message sent to Client = Sat Sep 25 15:08:28 IST 2010

In this way two application programs running on two different machines can communicate with each other using java socket programming.