2013-03-21 4 views
18

У меня есть проблема с использованием ServerSocket в моем приложении.Создание ServerSocket в отдельном потоке?

Я создаю ServerSocket в конструкторе моего приложения. Конструктор сокета вызывает метод accept() для ожидания подключения клиента.

Проблема в том, что метод accept() замораживает все мое приложение до тех пор, пока клиент не подключится. Поэтому я хотел бы спросить, есть ли альтернатива созданию целого ServerSocket в отдельном потоке, что конструктор ServerSocket и его метод accept() вызывается рядом с моим основным приложением?

Edit:

Благодаря Оливье за ​​совет, ставящие Признавайте в работоспособной и создавая ThreadPool для обработки clientconnections.

Thats мой код прямо сейчас:

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 работает нормально! Благодаря!

+0

попытался перемещение сокета кода, связанный в отдельном потоке? возникла ли какая-либо конкретная проблема? – Ankit

+0

Посмотрите на java.nio.channels.AsynchronousServerSocketChannel и посмотрите, соответствует ли оно вашим требованиям. – Crollster

+0

Или еще лучше, взгляните на этот вопрос: http://stackoverflow.com/questions/8940747/how-should-i-use-asynchronousserversocketchannel-for-accepting-connections – Crollster

ответ

34

Обычно я использую N + 1 потоков для этого: один для ServerSocket, чтобы избежать блокировки всего приложения, ожидающего подключения клиента; и 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(); 
      } 
     } 
    } 

} 
+0

С помощью threadpool, обрабатывающей клиентов, как вы обрабатываете получение и отправку данных клиенту и от него? Одно из решений, которое я видел несколько недель назад, было то, что Hanlder также имеет 2 потока, один для отправки и один для приема данных. – Loki

+0

Кроме того, для очень похожего, но немного более подробного описания этой темы, см. Следующую статью: [http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html](http: //tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html) –

+0

Этот код не помогает против атаки на отказ в обслуживании, где [accept] (http://man7.org/linux/ man-pages/man2/accept.2.html) блокируется (или дросселируется) злоумышленником. Такой злоумышленник остановит ваш сервер от принятия новых клиентов. –

Смежные вопросы