How to build a server in Java: Allowing multiple users to connect

Servers with multiple connections

Right now, our server allows one user to connect and then just prints out what that user has sent to the server. Now that’s cool but it isn’t really very useful. Wouldn’t it be awesome if multiple connections would be allowed and we could actually chat? Well then, let’s do it!

If you haven’t already please check out Part 1 and Part 2 of this tutorial series.

So what do we need to add?

Well, in order to allow multiple connections to our server we need to add something called threads. Threads essentially are the things that allow multitasking on our computers and let us run more than one thing at a time. For example, you can listen to music while writing your essay, there is a thread running the music player and a thread running your word processor and then can perform their own functions separately. So, we can set up a thread for each person who connects to our server which will allow us to have tons of people to connect to our server. If you haven’t the slightest clue what a thread is then unfortunately this tutorial might not work out so well for you, try researching threads online (there are tons of tutorials out there about them) and then come back here.

Threads

Here is some code that will show you how we will be using threads to allow multiple connections:

1
2
3
Socket socket = sSocket.accept();
Thread socketThread = new ThreadClass(socket);
socketThread.start();

We will run this code every time someone connects and this will essentially place their connection in it’s own thread. This thread will handle everything for that one client. Unfortunately we can’t just say “RUN THE SOCKET” and it will suddenly magically receive connections from the client, print them out, and send them to all the other clients. So, we essentially create our own custom thread. Here is some code that will outline how this will work:

//We need to use "implements Runnable to tell Java that this is a thread
 class ClientThread implements Runnable {
 //This run method is what is executed when the thread starts
 public void run()
 {
 //Set up the PrintWriter and BufferedReader here
 while(true) {
 //Get info sent from client
 String clientInput = input.nextLine();
 //Here would would have a for loop that would send the
 //client's message to every other client connected.
 }
 }
 }
Okay, now that you know a little about threads and what we’re going to do with them lets redo the server code.

The New Server Code

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

public class Server
{
    public static void main(String[] args)
    {
        new Server();
    }

    public Server()
    {
        //We need a try-catch because lots of errors can be thrown
        try {
            ServerSocket sSocket = new ServerSocket(5000);
            System.out.println("Server started at: " + new Date());


            //Loop that runs server functions
            while(true) {
                //Wait for a client to connect
                Socket socket = sSocket.accept();



                //Create a new custom thread to handle the connection
                ClientThread cT = new ClientThread(socket);

                //Start the thread!
                new Thread(cT).start();

            }
        } catch(IOException exception) {
            System.out.println("Error: " + exception);
        }
    }

    //Here we create the ClientThread inner class and have it implement Runnable
    //This means that it can be used as a thread
    class ClientThread implements Runnable
    {
        Socket threadSocket;

        //This constructor will be passed the socket
        public ClientThread(Socket socket)
        {
            //Here we set the socket to a local variable so we can use it later
            threadSocket = socket;
        }

        public void run()
        {
            //All this should look familiar
            try {
                //Create the streams
                PrintWriter output = new PrintWriter(threadSocket.getOutputStream(), true);
                BufferedReader input = new BufferedReader(new InputStreamReader(threadSocket.getInputStream()));

                //Tell the client that he/she has connected
                output.println("You have connected at: " + new Date());

                while (true) {
                    //This will wait until a line of text has been sent
                    String chatInput = input.readLine();
                    System.out.println(chatInput);
                }
            } catch(IOException exception) {
                System.out.println("Error: " + exception);
            }
        }
    }
}

The Explanation

So for this new code you can see that we only have to change the server’s code. You can use the client code from the last tutorial to connect to the server. The main thing now is that, each time a socket connection is accepted, that socket is passed off to a thread which runs the socket. Once that socket has been passed off to the thread the server then waits for a new socket connection.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s