2012-10-19 41 views
10

Tôi đã chạy một vài thử nghiệm với ổ cắm và gặp phải một số hành vi lạ: ServerSocket sẽ từ chối kết nối sau khi ổ cắm máy khách thứ 50 kết nối với nó, ngay cả khi ổ cắm máy khách đó đóng trước khi ổ cắm tiếp theo được mở ra, và thậm chí nếu độ trễ được thêm vào giữa các kết nối.Giới hạn kết nối Java ServerSocket?

Chương trình sau là mã thử nghiệm của tôi, ở trạng thái hiện tại, không có ngoại lệ và kết thúc bình thường. Tuy nhiên, nếu kích thước mảng của Socket[] clients được tăng vượt quá 50, bất kỳ ổ cắm máy khách nào cố kết nối sau khi kết nối thứ 50 bị từ chối bởi ổ cắm máy chủ.

Câu hỏi: Tại sao số lượng kết nối ổ cắm bị từ chối bởi ổ cắm máy chủ?

public static void main(String[] args) { 
    try (ServerSocket server = new ServerSocket(2123)) { 
     Socket[] clients = new Socket[50]; 
     for (int i = 0; i < clients.length; i++) { 
      clients[i] = new Socket("localhost", 2123); 
      System.out.printf("Client %2d: " + clients[i] + "%n", i); 
      clients[i].close(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

Tôi đã chạy thử nghiệm nơi khác 50 ổ cắm kết nối với một máy chủ cục bộ, và không có vấn đề xảy ra với 100 ổ cắm được mở ra và đóng lại, vì vậy tôi đã suy luận rằng các ổ cắm máy chủ của nó là từ chối kết nối, và không một số giới hạn mở ổ cắm máy khách, nhưng tôi đã không thể phát hiện tại sao ổ cắm máy chủ bị giới hạn ở 50 kết nối, mặc dù chúng không được kết nối đồng thời.

Trả lời

12

Đó là tất cả trong JavaDoc:

Chiều dài hàng đợi tối đa đối với chỉ dẫn kết nối đến (yêu cầu kết nối) được thiết lập đến 50. Nếu một dấu hiệu kết nối đến khi hàng đợi đầy, kết nối bị từ chối.

Dường như ServerSocket của bạn không bao giờ chấp nhận bất kỳ kết nối nào, chỉ cần nghe. Bạn có thể phải gọi accept() và bắt đầu xử lý các kết nối hoặc tăng hàng đợi tồn đọng kích thước:

new ServerSocket(port, 100) 
+2

Các kết nối trong hàng đợi có bị xóa khi các ổ cắm máy khách bị đóng không? – Vulcan

+1

@Vulcan Rõ ràng là không. – EJP

+1

@EJP Vâng, nhưng tại sao họ lại không?Đối với tôi, có vẻ như kỳ quặc rằng các ổ cắm kín vẫn được xếp hàng đợi để kết nối. Tôi đoán rằng không có cách nào cho các ổ cắm máy chủ để biết rằng các ổ cắm khách hàng đóng cửa mặc dù. – Vulcan

2

Dưới đây là một ví dụ mà làm việc, phù hợp với câu trả lời @ TomaszNurkiewicz của:

import java.net.*; 
import java.util.concurrent.atomic.AtomicBoolean; 

public class SockTest{ 
public static void main(String[] args) { 
    final AtomicBoolean shouldRun = new AtomicBoolean(true); 
    try { 
     final ServerSocket server = new ServerSocket(2123); 
     Thread serverThread = new Thread(){ 
      public void run() { 
       try { 
       while(shouldRun.get()) { 
       Socket s = server.accept(); 
       s.close(); 
      Thread.sleep(1); 
       } 
       } catch(Exception ex) { 
       ex.printStackTrace(); 
       } 
      } 
     }; 
     serverThread.start(); 
     Socket[] clients = new Socket[150]; 
     for (int i = 0; i < clients.length; i++) { 
      clients[i] = new Socket("localhost", 2123); 
      System.out.printf("Client %2d: " + clients[i] + "%n", i); 
      clients[i].close(); 
     } 
     shouldRun.set(false); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     shouldRun.set(false); 
    } 

    } 
} 
+0

Cảm ơn; Tôi thực sự tạo ra một ví dụ tương tự sau khi nhìn thấy câu trả lời của @ TomaszNurkiewicz trước đó, nhưng không được làm sạch như bạn (tôi quên AtomicBoolean và tạo lớp tạm thời của riêng tôi với cùng chức năng haha). +1 – Vulcan

0

Hai điều bạn có thể xem

  1. Máy chủ không chấp nhận kết nối.
  2. Máy chủ không thể phục vụ quá nhiều kết nối cùng một lúc. Nó có thể gây ra bởi tăng backlog (ngoài 50). Hãy thử cho một số khoảng cách thời gian trong vài giây trước khi kết nối lại với máy chủ. Giống như đoạn đường nối lên. Tôi giải quyết nó bằng cách cho một khoảng cách thời gian khi tôi chạy thử tải.
Các vấn đề liên quan