2013-03-21 31 views
18

Tôi gặp sự cố khi sử dụng số ServerSocket trong đơn đăng ký của mình.Tạo ServerSocket trong một chuỗi riêng biệt?

Tôi đang tạo ServerSocket trong hàm tạo của ứng dụng của mình. Hàm khởi tạo của socket gọi phương thức accept() để đợi máy khách kết nối.

Vấn đề là phương pháp accept() đang đóng băng toàn bộ ứng dụng của tôi cho đến khi khách hàng kết nối. Vì vậy, tôi muốn hỏi nếu có một thay thế để tạo ra toàn bộ ServerSocket trong một chủ đề riêng biệt, rằng các nhà xây dựng của ServerSocket và phương pháp accept() của nó được gọi là bên cạnh ứng dụng chính của tôi?

Edit:

Nhờ Olivier cho những lời khuyên, đưa .Đồng ý vào một Runnable và tạo ra một threadpool để xử lý các clientconnections.

Thats mã của tôi ngay bây giờ:

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 chạy tốt! Cảm ơn!

+0

cố gắng di chuyển ổ cắm mã liên quan trong chủ đề riêng biệt? bất kỳ vấn đề cụ thể phải đối mặt? – Ankit

+0

Hãy xem java.nio.channels.AsynchronousServerSocketChannel và xem liệu nó có phù hợp với yêu cầu của bạn hay không. – Crollster

+0

Hoặc vẫn tốt hơn, hãy xem câu hỏi này: http://stackoverflow.com/questions/8940747/how-should-i-use-asynchronousserversocketchannel-for-accepting-connections – Crollster

Trả lời

34

Thông thường, tôi sử dụng các chủ đề N + 1 cho điều này: một cho ServerSocket, để tránh chặn toàn bộ ứng dụng chờ khách hàng kết nối; và N chủ đề để xử lý các yêu cầu của khách hàng, N là kích thước của hồ bơi thread (Tôi khuyên bạn nên sử dụng một hồ bơi thread trên tạo ra một chủ đề mới cho mỗi khách hàng).

Dưới đây là một ví dụ (chỉ cần mã hóa nó, bạn có thể muốn có quản lý ngoại lệ tốt hơn và như vậy, nhưng đây là một ví dụ làm việc tối thiểu)

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

Với threadpool xử lý các khách hàng, làm thế nào để bạn xử lý Nhận và gửi dữ liệu đến và đi từ khách hàng? Một giải pháp tôi thấy một vài tuần trước đây là Hanlder cũng có 2 chủ đề, một cho việc gửi và một để nhận dữ liệu. – Loki

+0

Ngoài ra, đối với chủ đề này rất giống nhưng mô tả chi tiết hơn, hãy xem bài viết sau: [http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html](http: //tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html) –

+0

Mã này không giúp chống lại cuộc tấn công từ chối dịch vụ, nơi [chấp nhận] (http://man7.org/linux/ man-pages/man2/accept.2.html) bị kẻ tấn công chặn (hoặc throttled). Kẻ tấn công như vậy sẽ ngăn máy chủ của bạn chấp nhận khách hàng mới. –

Các vấn đề liên quan