A Multi-Threaded TCP Server

Introduction

In the the section called “The TCP Client/Server” we developed a full client/server application. The server we developed could only handle one connection at a time. It was structured to create a HandleConnection object for each conneciton that was made to the server, however, since the DateServer waits for the HandleConnection object to deal with the DateClient then it cannot handle any further connections at the same time. You can see this if you run the server and then connect to it with two clients at the same time - the server will refuse the connectiona as it is busy serving the current client on port 5050 and has not started listening again.

The Server has however been structured correctly to make it easily threaded by keeping the connection handler separate from the Server. All that has to be done is to make this connection handler (the HandleConnection class) threaded. Once it is threaded the server can create a separate thread for every client that connects, where the thread deals completely with that client. When the client disconnects this thread can finish.

To make the server threaded we can take the HandleConnection class from the section called “The TCP Client/Server” and modify it, by making it inherity from the Thread class and over-riding the run() method of the Thread class.

The DateServer has to be modified slightly to create an object of our new ThreadedHandleConnection class and to call the start(), method rather than calling the thread's run() method directly.

If we do this the ThreadedDateServer code should look like:

 1 
 2 
 3   ...
 4 
 5   public class ThreadedDateServer 
 6   {
 7     public static void main(String args[])
 8     {
 9       ...
10       
11       // Create the Handle Connection object - our new thread 
12       // object - only create it
13       ThreadedHandleConnection con = new ThreadedHandleConnection(clientSocket);
14       
15       if (con == null) //If it failed send and error message
16       {
17         ...
18       }
19       else { con.start(); } // otherwise we have not failed 
20         // to create the HandleConnection object - start this thread now
21       }
22       
23       ...
24         
25 

And the ThreadedHandleConnection code should look like:

 1 
 2 
 3   public class ThreadedHandleConnection extends Thread
 4   {
 5 
 6     private Socket clientSocket;    // Client socket object
 7     private ObjectInputStream is;   // Input stream
 8     private ObjectOutputStream os;  // Output stream
 9     private DateTimeService theDateService;
10     
11     // The constructor for the connecton handler
12 
13     public ThreadedHandleConnection(Socket clientSocket) 
14     {
15         this.clientSocket = clientSocket;
16 
17         //Set up a service object to get the current date and time
18         theDateService = new DateTimeService();
19     }
20 
21     // The main thread execution method 
22 
23     public void run() 
24     {
25         String inputLine;
26  		...
27     }
28     
29     ... etc. (full code below - no changes from here on)
30 
31 

To make it easier for you to see this update, I have placed all the source files here: