Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating the ServerSocket in a separate thread?

I have a problem with using a ServerSocket in my application.

I'm creating the ServerSocket in the constructor of my application. The constructor of the socket calls the accept() method to wait for a client to connect.

The problem is that the accept() method is freezing my whole application until a client connects. So I would like to ask if there's an alternative to creating the whole ServerSocket in a separate thread, that the constructor of the ServerSocket and its accept() method is called beside my main application?

Edit:

Thanks to Olivier for the advice, putting the .accept into a runnable and creating a threadpool to handle the clientconnections.

Thats my code right now:

  public void start(){        final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);        Runnable serverTask = new Runnable() {           @Override           public void run() {                try {                   serverSocket = new ServerSocket(port);                    while (true) {                       Socket clientSocket = serverSocket.accept();                       objectout = new ObjectOutputStream(clientSocket.getOutputStream());                       clientProcessingPool.submit(new ClientTask(clientSocket,objectout));                    }               } catch (IOException e) {                   System.err.println("Accept failed.");               }            }       }; 

Everythings running fine! Thanks!

like image 329
Chocolate Avatar asked Mar 21 '13 07:03

Chocolate


1 Answers

Usually, I use N+1 threads for this : one for the ServerSocket, to avoid blocking the whole application waiting for a client to connect; and N threads to process the client's requests, N being the size of the thread pool (I recommend using a thread pool over creating a new thread per client).

Here is an example (just coded it, you may want to have better exception management and such, but this is a minimal working example)

public class Server {      public static void main(String[] args) {         new Server().startServer();     }      public void startServer() {         final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);          Runnable serverTask = new Runnable() {             @Override             public void run() {                 try {                     ServerSocket serverSocket = new ServerSocket(8000);                     System.out.println("Waiting for clients to connect...");                     while (true) {                         Socket clientSocket = serverSocket.accept();                         clientProcessingPool.submit(new ClientTask(clientSocket));                     }                 } catch (IOException e) {                     System.err.println("Unable to process client request");                     e.printStackTrace();                 }             }         };         Thread serverThread = new Thread(serverTask);         serverThread.start();      }      private class ClientTask implements Runnable {         private final Socket clientSocket;          private ClientTask(Socket clientSocket) {             this.clientSocket = clientSocket;         }          @Override         public void run() {             System.out.println("Got a client !");              // Do whatever required to process the client's request              try {                 clientSocket.close();             } catch (IOException e) {                 e.printStackTrace();             }         }     }  } 
like image 197
Olivier Croisier Avatar answered Sep 20 '22 05:09

Olivier Croisier