In todays article we will talk about networking and how we can design a multi user server using Java networking library and built in thread features.

Before we begin lets talk about Sockets a bit.

A Socket is defined as an endpoint in a two way communication between software programs running on a network and serves as a point which sends and receives data.

Definition of Sockets

In our scenario, there are two endpoints – one is server and other one is client.

It is important to understand the two types of socket programming – Connection Oriented and Connection-less socket programming. In this article we will see the former one.

About the Program

In this article we will see how to write a server which is capable of connecting to multiple clients at the same time and communicate with them by exchanging messages. The server will be running on our localhost on port 8080. We will be using telnet in-order to connect to the server as clients and exchange messages with server. There will not be any separate client program.

Creating the Server…

A server running on our localhost can be created using ServerSocket class.

import java.io.IOException;
import java.net.ServerSocket;
/**
* @author Seyed Sahil
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
serverSocket.close();
}
}
  • The port number is passed as an argument to the constructor.
  • The constructor will throw java.net.BindException which is a subclass of java.io.IOException if the port specified is already in use means some other program is listening to the same port.
  • A socket server should be closed after its use. this will throw an java.io.IOException if an any I/O error while closing the socket.

Listening for Clients…

Once our server is up and running, the server has to listen for incoming connections.

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Seyed Sahil
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Waiting for clients…");
Socket clientSocket = serverSocket.accept();
clientSocket.close();
serverSocket.close();
}
}
  • Calling accept() method will block the execution of server at the given point and wait for an incoming connection and this will block the program.
  • There is chance of getting java.io.IOException if there is any I/O error while waiting for the connection.
  • The method will return a Socket object upon connecting to client and this can be used for communicating with that client.

Communicate with a Single Client…

For communicating with the client, the server has to obtain the input and output streams associated with the client socket.

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Seyed Sahil
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Waiting for clients…");
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
}
  • Output stream will be used to send messages to client.
  • Input stream will be used to receive message from client.
  • Remember before closing the connections – we will have to close the input and output streams.

Connecting to the Server…

We will be using telnet protocol to connect and communicate with the client. Open the command prompt and type in the following command.

> telnet localhost 8080

If you are using Windows operating system and telnet is not enabled please enable it form Programs and Features. Lets take a look at the output.

Single Client Demo

As you can see, server is sending a message to client as soon as the connection is established, client enter the name to which server replies with another message.

To understand the drawback of the above given program, lets imagine a situation where the server is waiting for the input from the client. What if another client tries to connect with the server ? Lets take a look at the screenshot below.

Multi Client Demo

As you can see, the second client has to wait until the first client finishes. The code is given below.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.Date;
/**
* @author Seyed Sahil
*/
public class App {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Server session started at " + new Date());
int connections = 0;
while (connections != 2) {
System.out.println("Server is listening on port 8080");
Socket clientSocket = serverSocket.accept();
connections++;
System.out.println("Server connected with Client-" + connections + " at " + new Date());
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println("Hello Client-" + connections + ", What is your name ?");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("Hey " + in.readLine() + ", Nice to meet you!");
in.close();
out.close();
clientSocket.close();
}
serverSocket.close();
}
}

Creating a Multi User Server…

This is pretty straight forward. If we take a look at the previous code, after accepting the connection from a client, the program gets blocked while serving the client. How we can eliminate this ?

The answer is Threads.

As soon as the client is connected, start a new thread to handle the connection. This will not block the server while serving the first client. The thread started can communicate with the client using the socket obtained without blocking the main server thread. Once the communication is done, the client connection can be closed at the thread level.

Take a look at the below code to understand how it is done.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Seyed Sahil
*/
public class App {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Server session started at " + new Date());
int connections = 0;
List<Thread> connectionThreads = new ArrayList<>();
while (connections != 2) {
System.out.println("Server is listening on port 8080");
Socket clientSocket = serverSocket.accept();
connections++;
System.out.println("Server connected with Client-" + connections + " at " + new Date());
final int clientId = connections;
Thread connectionThread = new Thread(() -> {
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println("Hello Client-" + clientId + ", What is your name ?");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("Hey " + in.readLine() + ", Nice to meet you!");
in.close();
out.close();
clientSocket.close();
} catch (IOException exception) {
exception.printStackTrace();
}
});
connectionThread.start();
connectionThreads.add(connectionThread);
}
for (Thread connectionThread : connectionThreads) {
connectionThread.join();
}
serverSocket.close();
}
}
  • The communication with the client is done by the thread and so it will not block the other clients.
  • The client socket is closed inside the thread.
  • Server socket is closed only after all the active threads are completed.

Take a look at the below given screen shot

Multi Client Demo

That’s it – We are Done! We have created a server capable of handling more than one connection at the same time. 🙂

Accessing the Complete Code…

Hope you understood the tutorial and the code given above. Are you looking for a more reusable code of the multi user server ?

You can download the full code from my git repository below 🙂

https://github.com/seyedsahil/socket-server-demo

Thank You

Seyed Sahil