web-dev-qa-db-ja.com

ServerSocketを別のスレッドで作成しますか?

アプリケーションでServerSocketを使用すると問題が発生します。

アプリケーションのコンストラクターでServerSocketを作成しています。ソケットのコンストラクターはaccept()メソッドを呼び出して、クライアントが接続するのを待ちます。

問題は、クライアントが接続するまでaccept()メソッドがアプリケーション全体を凍結していることです。そこで、ServerSocketとそのaccept()メソッドのコンストラクターが私の横に呼び出されるように、別のスレッドでServerSocket全体を作成する代わりがあるかどうかを尋ねたいと思います。メインアプリケーション?

編集:

アドバイスをくれたOlivierに感謝します。

それが今の私のコードです:

  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.");
              }

          }
      };

すべてが正常に動作しています!ありがとう!

21
Chocolate

通常、これにはN + 1スレッドを使用します。クライアントが接続するのを待っているアプリケーション全体をブロックすることを避けるために、ServerSocket用に1つです。クライアントの要求を処理するN個のスレッド。Nはスレッドプールのサイズです(クライアントごとに新しいスレッドを作成するよりもスレッドプールを使用することをお勧めします)。

以下に例を示します(コード化しただけで、より優れた例外管理などが必要になる場合がありますが、これは最小限の作業例です)

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();
            }
        }
    }

}
42