0

I am working on a program where I have a Server and Client class, but at the moment it only handles only one client at a time. I need the server to be able to handle multiple clients concurrently (simultaneously), using multithreading.

Here is my Server code; how can I change it to handle multiple clients concurrently?

public static void main(String[] args) throws IOException {

       ServerSocket socket = new ServerSocket(8945);
       Server serverInstance = new Server();

       System.out.println("Server is running. Waiting for client.");

       while(true) {
           server.socket = s.accept();
           System.out.println("Client connected");
           serverInstance.run();
           System.out.println("Client disconnected. Waiting for new client.");
       }
   }

   public void run() {
       try {
           try {
               in = new Scanner(socket.getInputStream());
               out = new PrintWriter(socket.getOutputStream());
               RequestHandlingMethod();  

           } finally {
               socket.close();
           }

       } catch (IOException e) {
           System.err.println(e);
       }

}

1 Answer 1

1

Create a separate class that handles the client. Make it implement Runnable so that you can just start a separate Thread with it.

public class ClientHandler implements Runnable {

   private final Socket socket;

   public ClientHandler(Socket socket) {
     this.socket = socket;
   }

    public void run() {
       try (Socket socket = this.socket;
            Scanner in = new Scanner(socket.getInputStream();
            PrintWriter out = new PrintWriter(socket.getOutputStream()) {

               //todo: do whatever you need to do


       } catch (IOException ex) {
           ex.printStackTrace();
       }

       System.out.println("Client disconnected.");
    }  
}

Then in your server you do:

       System.out.println("Waiting for new client connection");
       Socket clientSocket = s.accept();
       System.out.println("Client connected");
       new Thread(new ClientHandler(clientSocket)).start();

If you don't want to create a lot of disposable Threads, you might want to consider using an ExecutorService with a cached thread pool (or another thread pool of your choice if you prefer).

You would just create a new ExecutorService with ExecutorService executor = ExecutorService.newCachedThreadPool() and then inside your loop you do:

       System.out.println("Waiting for new client connection");
       Socket clientSocket = s.accept();
       System.out.println("Client connected");
       executor.submit(new ClientHandler(clientSocket));

If you think you are going to have a lot of concurrent clients, you might want to look at using a non-blocking server with NIO instead. It will have 1 single event loop thread instead (doesn't block on the accept) and handles all I/O events in there, and you can have a pool of worker threads that do the client handling logic.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.