Java Socket & ServerSocket Tutorial

In this article you will learn how to program a very basic Client-Server application.
The communication between the client and the server will be unidirectional. Said in other words, there will only be a one-way communication between the client and the server.

We’ll also write some very simple tests alongside with this tutorial. The tests will simply test the constructors of both the Client and the Server. We’ll follow up the test setup at a later time, writing tests using mock-objects for the client and the server.

The Client Class

To establish a connection between two machines, we need a Socket. When constructing a socket, we need to provide it with information about the server’s network address. 
The server’s network address consists of two things: The IP-address, and the port number (which range from 0 – 65 535). That’s all there is to it.

So, to construct a Socket-object and connect it to a particular IP-address at a given port, we simply write:

Socket socket = new Socket("127.0.0.1", 45000);

Note that the IP-address provided here is actually the localhost, meaning your own machine! This gives you the ability to test the following client and server application on your own machine.

Okay, let’s jump straight to it: Here’s the Client class. The methods are commented, so please refer to them.

Let’s go through it, one method at a time.

We first notice that we have five member variables:

  • socket: This will be used to connect to the Server.
  • inputStream: This will provide a way to read input from the keyboard
  • outPutStream: The DataOutputStream will write data to the server, by using the Socket’s own outputstream.
  • ipAddress: The IP-address of the server
  • port: The port number to connect to (which the server ultimately have to listen on).

Next is the constructor, located at line 41-48.
First, we simply check whether the IP-address is null, and whether the provided portnumber is valid (between 0 – 65 535). If the IP-address is null, or the portnumber is invalid, we throw an IllegalArgumentException.
The rest of the constructor is pretty straight forward – we assign the provided values to the ipAddress and the portnumber, and set up our DataInputStream.
Notice that the DataInputStream is constructed with the parameter System.in. This simply means that we want to take input from the keyboard!

Further we have the connect() method, line 56-73.
The connect method starts by initiating a Socket object (using the method getSocket() at line 100-107).
If the getSocket() method fails by any means, it returns null. We handle this by null-checking the socket at line 59, throwing an UnknownHostException if the Socket is null.

We’ve now gotten past the null-check, which means that the connection was successful.
At line 63 we initiate our DataOutputStream, and make a call to the private method sendOutput() on the next line.

The sendOutput method reads data from the inputStream (which was constructed with System.in), and writes that data to the outputStream. Everything inside that method is wrapped in a while-loop, which will terminate if the user enter “quit”.

Finally, when sendOutput has terminated, the connect() method proceeds by closing down the inputStream, outputStream and the socket.

You also might have noticed that a great part of the code has been wrapped in try-catch blocks? Well, that’s just something you’ll have to deal with, and we’ll write an article on java exceptions later on!

Now, all that’s left to run the client is to add the main method, line 109-116.
In the main method the Client is constructed with the IP-address “127.0.0.1” and the port 45000.

Try to run Client.java, and see what happens. Can you explain why?

When we try to run Client.java, we get an UnknownHostException. This is because our getSocket() method returns null if any error occurs when creating the socket. Further, in the connect() method we explicitly tell Java to trow an UnknownHostException if the socket object is null!
Why does this happen? Well, we haven’t created the Server yet!

The Server Class

Following is the Server class, which will be listening on a given port for connections.

The server class has four member variables:

  • socket: The Socket will be initiated when a client connects, creating a “tunnel” between the client and the server
  • server: The ServerSocket is the object responsible for listening on a given port. It returns a Socket object when a client connects.
  • inputStream: The InputStream is used to read any input that comes through the Socket.
  • port: The port number which the server will be listening on.

Next, we have the constructor. It simply checks that the port number is valid, and assigns the given port number to the private variable port.

At line 53 – 73 we have the establish() method. This is where the magic happens.
The method starts off by fetching a ServerSocket object from the private method getServerSocket. This is pretty straight forward.

Next, the socket is initiated, with the accept() method from the ServerSocket object. Now, this is a special kind of method.
The accept() method is what we call blocking. The code will not proceed to run before a client actually connects! So, line 58: This is where the Server actually listens for connections!
Whenever we fire up the Client and call the connect() method, the code in the server’s establish() method will proceed to run. This also tells us that we can only connect one client at any given time. Not great for a real life scenario..

When the Client has connected, we simply read the input from the Socket created earlier, and terminate when the Server receives “quit” from the Client.

All that’s left for the Server to run is to provide a main method, construct the Server, and call the establish() method!

Note: If you haven’t gotten it by now – Server must be started before the Client!

Now you can play around and be proud of your first networking application. Type something into the terminal window of the Client, and see how it reaches the Server!

Tests

Below are some very simple tests, testing the constructors of both the Client and the Server using JUnit. We’ll save Mock-objects for another time!

Tutorials will only get you so far..
If you wish to expand your Java skill-set and become an advanced Java developer, I personally recommend the Comprehensive Java Course by Edureka.
You can get 25% with the coupon code LIMITED25 😉

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *