Socket Programming in Java and introduction to TCP network


TCP is the reliable network which works on the point to point connection. The virtual channel is created for a reliable communication which ensures that no data packet is lost, this article introduces the Socket programming with the help of java.net package and ServerSocket and socket class.

The TCP is a protocol well known for its reliability of data transmission. The work of TCP depends on a protocol known as two way handshake protocol. In this the server and client both agree on the start of communication and then a virtual point to point channel is created between them to start the transmission. The TCP stands for transmission control protocol.

This is reliable because it ensures that data is transmitted at the other end. On the zero level it uses the acknowledgement phenomenon. However while working with Java we don't need to worry about the ground zero. Java programming language provide the classes Socket and ServerSocket which takes care of all the other matters, you only need to worry about the application configuration.

Following are the steps need to be taken in order to establish a transmission channel and transmit data between the server and client using Socket and ServerSocket.

1. Create a ServerSocket which will declare itself on a specified port number.
2. Client creates the Socket object which will try to contact the server on the port, on which server declared its service.
3. Server need to accept the communication request from the client, for this purpose we can use the accept() method of ServerSocket and it will use the reference of the Socket to take further communication control.
4. The Socket class provide the access to Input and Output Streams which in turns may be used by either server or client to send and receive data from each other.
5. getInputStream() and getOutoutStream() are the two methods provided by the socket class to process the information along the channel.

If you understand the theory now is the time to demonstrate a practical example, for this purpose we will be using ServerClass and ClientClass. These are as names suggests, server and client respectively which will transmit and receive the messages along the channel. We have placed some outputs to show how the complete process goes.


package networking;
import java.io.*;
import java.net.*;

public class ServerClass {
    public static void main(String[] args){
        try{
            System.out.println("creating server socket..");
            ServerSocket ss = new ServerSocket(5000);
            System.out.println("created server socket");
            System.out.println("waiting for connection");
            Socket cs = ss.accept();
            System.out.println("connection accepted");
            PrintWriter bw = new PrintWriter(cs.getOutputStream(),true);
            BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
            bw.println("Hi Client!");
            bw.flush();
            System.out.println(br.readLine());
        }
        catch(Exception i){
            System.out.println(i);
        }
    }
}

Note: Exception handling is necessary as there may be exceptions occurring. However these are caught type exceptions so compiler will be telling you why you need them.

So as we see in the program there is a ServerClass which declares itself on the port number 5000. If any client want it may connect this server at this port. After declaring its existence the server program will wait for any incoming connections. And when we run the client program it will accept that using accept() method and proceed.

As you can see in the program the socket object we get in return from accept() method is stored in cs reference and on this we call getOutputStream() and getInputStream() which returns us the respective streams which we wrap in the PrintWriter and BufferedReader to take advantages of the under lying streams.

We have used the println() and flush() to transmit data on network channel and readLine() to read from network channel. There are other methods too which you can use according to your needs.

The client side program is kind of similar except that there is no ServerSocket object and InetAddress is used to give server its own identity.


package networking;

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

public class ClientClass {

    public static void main(String[] args) {
        try {
            Socket s = new Socket("localhost", 5000);
            PrintWriter bw = new PrintWriter(s.getOutputStream(), true);
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            bw.println("Hi Server!");
            bw.flush();
            System.out.println(br.readLine());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

There is everything nearly the same. So now let us see the running of these programs which will result following result.

Step 1: Run server program

creating server socket..
created server socket
waiting for connection

Step 2: run the client program

Hi Client!

Step 3: check back the server side for what change we see in output

creating server socket..
created server socket
waiting for connection
connection accepted
Hi Server!

You see the result, after we run the client program the server which was waiting for any connection, accepts the coming connection from client and proceed further with the program.

This is quite much to know about the Socket Programming in Java. If you want to know how you are going to manage the running of these two programs simultaneously without termination one of them please read on.

Note: That port 0 to 1023 are already reserved to some standard services and uses, so you can use anything above this, taking in account that any other service is not using that port on the same host.

How to Run The programs:

As you see there are two different classes and you have to run these both simultaneously to check the working, so here is what you need to do.

Running from the command line:
1. you will need to run two different command terminals.
2. first track down the location of the server file and compile and run it.
3. Now, without closing the server terminal, go to the other terminal and track down and run the client program.
4. Now you can check the result and working of these two programs together.

Running from IDE:
1. Running from IDE is easier than running from command line.
2. First right click the server file and run it, the IDE will output the result on the console.
3. Now do the same with the client file and the IDE will open another console to show the result.
4. You can switch through the the consoles to check the result.