Java Socket Programming Tutorial

1- What is Socket?

On the server-side:
  • Normally, a server runs on a specific computer and has a socket (Server socket) that is bound to a specific port number. The server just waits, listening to the socket for a client to make a connection request.

On the client-side:
  • The client knows the hostname of the machine on which the server is running and the port number on which the server is listening. To make a connection request, the client tries to rendezvous with the server on the server's machine and port. The client also needs to identify itself to the server so it binds to a local port number that it will use during this connection. This is usually assigned by the system.
General illustration:
If everything goes well, the server accepts the connection. Upon acceptance, the server gets a new socket bound to the same local port and also has its remote endpoint set to the address and port of the client. It needs a new socket so that it can continue to listen to the original socket for connection requests while tending to the needs of the connected client.

On the client side, if the connection is accepted, a socket is successfully created and the client can use the socket to communicate with the server.

The client and server can now communicate by writing to or reading from their sockets.

Data written to the output stream on Socket of the client will receive on the input stream of Socket at Server. And vice versa, data written to the output stream  on  Socket of Server will get on stream at the client's input Socket.

Definition: 

A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to.

2- Simple example with Socket

SimpleServerProgram.java
package org.o7planning.tutorial.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServerProgram {

   public static void main(String args[]) {

       ServerSocket listener = null;
       String line;
       BufferedReader is;
       BufferedWriter os;
       Socket socketOfServer = null;

       // Try to open a server socket on port 9999
       // Note that we can't choose a port less than 1023 if we are not
       // privileged users (root)

 
       try {
           listener = new ServerSocket(9999);
       } catch (IOException e) {
           System.out.println(e);
           System.exit(1);
       }

       try {
           System.out.println("Server is waiting to accept user...");

           // Accept client connection request
           // Get new Socket at Server.    
           socketOfServer = listener.accept();
           System.out.println("Accept a client!");

           // Open input and output streams
           is = new BufferedReader(new InputStreamReader(socketOfServer.getInputStream()));
           os = new BufferedWriter(new OutputStreamWriter(socketOfServer.getOutputStream()));


           while (true) {
               // Read data to the server (sent from client).
               line = is.readLine();
               
               // Write to socket of Server
               // (Send to client)
               os.write(">> " + line);
               // End of line
               os.newLine();
               // Flush data.
               os.flush();  


               // If users send QUIT (To end conversation).
               if (line.equals("QUIT")) {
                   os.write(">> OK");
                   os.newLine();
                   os.flush();
                   break;
               }
           }

       } catch (IOException e) {
           System.out.println(e);
           e.printStackTrace();
       }
       System.out.println("Sever stopped!");
   }
}
SimpleClientDemo.java
package org.o7planning.tutorial.socket;

import java.io.*;
import java.net.*;

public class SimpleClientDemo {

   public static void main(String[] args) {

       // Server Host
       final String serverHost = "localhost";

       Socket socketOfClient = null;
       BufferedWriter os = null;
       BufferedReader is = null;

       try {
           
           // Send a request to connect to the server is listening
           // on machine 'localhost' port 9999.
           socketOfClient = new Socket(serverHost, 9999);

           // Create output stream at the client (to send data to the server)
           os = new BufferedWriter(new OutputStreamWriter(socketOfClient.getOutputStream()));


           // Input stream at Client (Receive data from the server).
           is = new BufferedReader(new InputStreamReader(socketOfClient.getInputStream()));

       } catch (UnknownHostException e) {
           System.err.println("Don't know about host " + serverHost);
           return;
       } catch (IOException e) {
           System.err.println("Couldn't get I/O for the connection to " + serverHost);
           return;
       }

       try {

           // Write data to the output stream of the Client Socket.
           os.write("HELO");
 
           // End of line
           os.newLine();
   
           // Flush data.
           os.flush();  
           os.write("I am Tom Cat");
           os.newLine();
           os.flush();
           os.write("QUIT");
           os.newLine();
           os.flush();


           
           // Read data sent from the server.
           // By reading the input stream of the Client Socket.
           String responseLine;
           while ((responseLine = is.readLine()) != null) {
               System.out.println("Server: " + responseLine);
               if (responseLine.indexOf("OK") != -1) {
                   break;
               }
           }

           os.close();
           is.close();
           socketOfClient.close();
       } catch (UnknownHostException e) {
           System.err.println("Trying to connect to unknown host: " + e);
       } catch (IOException e) {
           System.err.println("IOException:  " + e);
       }
   }

}

Running example:

First, you need to run class: SimpleServerProgram:
Next run class: SimpleClientDemo.

3- Socket + Thread example

Normally a connection between the server program and 1 Client is created, you should let them talk to each other on a thread, so each time a new connection to a new thread is created.
 
ServerProgram.java
package org.o7planning.tutorial.socketthread;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerProgram {

   public static void main(String args[]) throws IOException {

       ServerSocket listener = null;

       System.out.println("Server is waiting to accept user...");
       int clientNumber = 0;

       // Try to open a server socket on port 7777
       // Note that we can't choose a port less than 1023 if we are not
       // privileged users (root)

       try {
           listener = new ServerSocket(7777);
       } catch (IOException e) {
           System.out.println(e);
           System.exit(1);
       }

       try {
           while (true) {
               // Accept client connection request
               // Get new Socket at Server.

               Socket socketOfServer = listener.accept();
               new ServiceThread(socketOfServer, clientNumber++).start();
           }
       } finally {
           listener.close();
       }

   }

   private static void log(String message) {
       System.out.println(message);
   }

   private static class ServiceThread extends Thread {

       private int clientNumber;
       private Socket socketOfServer;

       public ServiceThread(Socket socketOfServer, int clientNumber) {
           this.clientNumber = clientNumber;
           this.socketOfServer = socketOfServer;

           // Log
           log("New connection with client# " + this.clientNumber + " at " + socketOfServer);
       }

       @Override
       public void run() {

           try {

               // Open input and output streams
               BufferedReader is = new BufferedReader(new InputStreamReader(socketOfServer.getInputStream()));
               BufferedWriter os = new BufferedWriter(new OutputStreamWriter(socketOfServer.getOutputStream()));

               while (true) {
                   // Read data to the server (sent from client).
                   String line = is.readLine();
                   
                   // Write to socket of Server
                   // (Send to client)                    
                   os.write(">> " + line);
                   // End of line.
                   os.newLine();
                   // Flush data.
                   os.flush();

           
                   // If users send QUIT (To end conversation).
                   if (line.equals("QUIT")) {
                       os.write(">> OK");
                       os.newLine();
                       os.flush();
                       break;
                   }
               }

           } catch (IOException e) {
               System.out.println(e);
               e.printStackTrace();
           }
       }
   }
}
ClientDemo.java
package org.o7planning.tutorial.socketthread;

import java.io.*;
import java.net.*;
import java.util.Date;

public class ClientDemo {

   public static void main(String[] args) {

 
       final String serverHost = "localhost";

       Socket socketOfClient = null;
       BufferedWriter os = null;
       BufferedReader is = null;

       try {
     
           
           // Send a request to connect to the server is listening
           // on machine 'localhost' port 7777.            
           socketOfClient = new Socket(serverHost, 7777);
     
           // Create output stream at the client (to send data to the server)
           os = new BufferedWriter(new OutputStreamWriter(socketOfClient.getOutputStream()));

     
           // Input stream at Client (Receive data from the server).
           is = new BufferedReader(new InputStreamReader(socketOfClient.getInputStream()));

       } catch (UnknownHostException e) {
           System.err.println("Don't know about host " + serverHost);
           return;
       } catch (IOException e) {
           System.err.println("Couldn't get I/O for the connection to " + serverHost);
           return;
       }

       try {
   
           // Write data to the output stream of the Client Socket.
           os.write("HELO! now is " + new Date());
       
           // End of line
           os.newLine();
       
           // Flush data.
           os.flush();  
           os.write("I am Tom Cat");
           os.newLine();
           os.flush();
           os.write("QUIT");  
           os.newLine();
           os.flush();

     
           
           // Read data sent from the server.
           // By reading the input stream of the Client Socket.
           String responseLine;
           while ((responseLine = is.readLine()) != null) {
               System.out.println("Server: " + responseLine);
               if (responseLine.indexOf("OK") != -1) {
                   break;
               }
           }

           os.close();
           is.close();
           socketOfClient.close();
       } catch (UnknownHostException e) {
           System.err.println("Trying to connect to unknown host: " + e);
       } catch (IOException e) {
           System.err.println("IOException:  " + e);
       }
   }

}