Socket Programming


WHAT IS SOCKET ?
Sockets provides communication between two computers using TCP (Transmission Control Protocol) network protocol 

So you might ask what is TCP protocol ?

Yes, TCP protocol is a network protocol that allows for reliable communication between two applications.

So we'll move into the socket programming 

The socket programming use client-server paradigm, which is roughly :

  1.  One program called serverClass that is waiting for the client's connection
  2.  A client class that makes connection with server class
  3. The server and the client exchange information until they are done
  4. The client and server both close their connection


Ok Look at the above diagram
As I mentioned before there are two types of blocks

  1. Server block
  2. Client block
First server block creates server sockets. 

Bind the socket to the specific server and port in the socket server object

According to the above diagram server socket is created by non argument constructor called :


       public serverSocket() throws IOException {

       }

 

When using this constructor, use the bind() method when you are ready to bind the server socket because using this constructor we are creating unbound server sockets. 

But if you are using parametrized constructors like

                   public serverSocket(int port) throws IOException {

                   }
       
 
you don't need to use bind() method because using this types of constructor we are creating bound server sockets.

Marks the connection mode socket using listen() method
This method will be used to accept incoming connection request using accept()

Wait for an incoming client connection
accept() method blocks until either a client connects to the server or sockets times out.

Client block creates sockets

Connect the socket to the specified host using connect()
Note that this connect method is needed only when you instantiate the socket using the no-argument constructor. 

Now connection is made between client and the server

The server and the client exchange information until they are done

After that the client and server both close their connection

That's all about the procedure 

Now we'll move into basic coding part

Running socket Client and Server as separate processes on the same computer





The client code
The following echoClient is a client program that connects to a server by using a socket and sends a message, and then waits for a response.


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Socket1;

import java.io.*;
import java.net.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class EchoClient {

    public static void main(String[] args) throws IOException {
        /* 
         This is to print the date and time 
         */
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
        /*
         These variables are to print the details of client and server
         */
        InetAddress ipAddress = null;
        String hostname = null;
        String message = null;

        String serverHostname = new String("127.0.0.1");
        int portNumber = 10007;

        /*
         This is to print the details of client and server
         */
        System.out.println("[CLIENT][" + dateFormat.format(new Date()) + "] - Initializing Simple Client");
        ipAddress = InetAddress.getLocalHost();
        hostname = InetAddress.getLocalHost().getHostName();

        System.out.println("[CLIENT][" + ipAddress + "][" + dateFormat.format(new Date()) + "] - Attemping to connect to host " + serverHostname + " on port " + portNumber);

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            // echoSocket = new Socket("taranis", 7);
            echoSocket = new Socket(serverHostname, portNumber);
            out = new PrintWriter(echoSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(
                    echoSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("[CLIENT][" + ipAddress + "][" + dateFormat.format(new Date()) + "] - Don't know about host: " + serverHostname + ":" + portNumber);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("[CLIENT][" + ipAddress + "][" + dateFormat.format(new Date()) + "] - Couldn't get I/O for the connection to: " + serverHostname  + ":" + portNumber);
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(
                new InputStreamReader(System.in));
        String userInput;

        System.out.print("[CLIENT][" + ipAddress + "][" + dateFormat.format(new Date()) + "] - Enter the message to send to " + serverHostname + ":" + portNumber + ": ");
        while ((userInput = stdIn.readLine()) != null) {
            out.println(userInput);
            System.out.println();
            System.out.println("[CLIENT][" + ipAddress + "][" + dateFormat.format(new Date()) + "] - Received " + in.readLine() + " from " + serverHostname + ":" + portNumber + ": ");
            System.out.print("[CLIENT][" + ipAddress + "][" + dateFormat.format(new Date()) + "] - Enter the message to send to " + serverHostname + ":" + portNumber + ": ");
        }

        out.close();
        in.close();
        stdIn.close();
        echoSocket.close();
    }
}

       
 

Look at the above code, client block create a socket with server hostname and portnumber.

The server code



/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Socket1;

import java.net.*;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class EchoServer {

    public static void main(String[] args) throws IOException {
        /* 
         This is to print the date and time 
         */
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
        /*
         These variables are to print the details of client and server
         */
        InetAddress ipAddress = null;
        String hostname = null;
        String message = null;
        /*
         This is the server-side socket
         */
        ServerSocket serverSocket = null;
        int          portNumber   = 10007;

        try {
            /*
             This is to print the details of client and server
             */
            System.out.println("[SERVER][" + dateFormat.format(new Date()) + "] - Initializing Simple Server");
            ipAddress = InetAddress.getLocalHost();
            hostname = InetAddress.getLocalHost().getHostName();

            serverSocket = new ServerSocket(portNumber);
        } catch (IOException e) {
            System.err.println("[SERVER][" + ipAddress + "][" + dateFormat.format(new Date()) + "][ERROR] - Could not listen on port: " + portNumber);
            System.exit(1);
        }

        Socket clientSocket = null;
        System.out.println("[SERVER][" + ipAddress + ":" + portNumber+"][" + dateFormat.format(new Date()) + "] - Waiting for connection.....");

        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("[SERVER][" + ipAddress + ":" + portNumber + "][" + dateFormat.format(new Date()) + "][ERROR] - Accept failed.");
            System.exit(1);
        }

        System.out.println("[SERVER][" + ipAddress + ":" + portNumber + "][" + dateFormat.format(new Date()) + "] - Connection successful.");
        System.out.println("[SERVER][" + ipAddress + ":" + portNumber + "][" + dateFormat.format(new Date()) + "] - Waiting for input.....");

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        String inputLine;

        while ((inputLine = in.readLine()) != null) {
            System.out.println("[SERVER][" + ipAddress + ":" + portNumber + "][" + dateFormat.format(new Date()) + "] - Server received: " + inputLine);
            System.out.println("[SERVER][" + ipAddress + ":" + portNumber + "][" + dateFormat.format(new Date()) + "] - Server sending back: " + inputLine);
            out.println(inputLine);

            if (inputLine.equals("Bye.")) {
            System.out.println("[SERVER][" + ipAddress + ":" + portNumber + "][" + dateFormat.format(new Date()) + "] - Terminating Server " + inputLine);
                break;
            }
        }

        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();
    }
}

       
 


First run the server








Next run the client








Now server is waiting for the input











Have you noticed that the terminal window display output of the server and client process in two different tabs. 

Use the client window to enter message to be sent to the server
ClientTerminal



Server Terminal

Check the hostname of the client and the server 

In this scenario both client and server are running on the same computer that's why 127.0.0.1-that is the IP address of the local computer. That is not the real scenario of the client server architecture. 

To run socket client and server on different computers You have to modify only one line of the client code. You need to give your partners IP Address.

        String serverHostname = new String("127.0.0.1");
        int portNumber = 10007;

 

These are the basic things of socket programming 

Comments

  1. Now I can understand this well... Thank you very much!!

    ReplyDelete
  2. neat explanation. good overview about socket programming

    ReplyDelete

Post a Comment

Popular posts from this blog

Quick start with TypeScript