2012-09-10 30 views
7

Tôi đang chạy hai trường hợp của stunnel trong Windows 7, được cấu hình để nghe cùng một cổng và dường như cả hai đều lắng nghe thành công trên cùng một cổng (chỉ cần sử dụng socket()/bind()/listen()). Cả hai trường hợp đều xuất hiện để thành công với tất cả các cuộc gọi và chúng hiển thị trong một netstat:Hai quy trình lắng nghe cùng một cổng trong Windows 7 như thế nào?

C:\>netstat -ano | grep 8000 
    TCP 0.0.0.0:8000   0.0.0.0:0    LISTENING  5828 
    TCP 0.0.0.0:8000   0.0.0.0:0    LISTENING  5852 

Người đầu tiên nghe được tất cả các yêu cầu đến.

Điều này hoàn toàn trái ngược với tất cả mong đợi của tôi. (Tôi đã mong đợi để có được EADDRINUSE nói với tôi cảng đã được bận rộn.) Vì vậy ....

  1. Tại sao/Làm thế nào để làm việc này? Hành vi này có hữu ích trong một số ngữ cảnh không?
  2. Tôi không muốn một cá thể chạy thành công nếu ứng dụng khác sắp bắt các yêu cầu gửi đến ... Làm cách nào để làm cho cổng độc quyền?

Trả lời

7

Điều này có thể thực hiện nếu ổ cắm được mở bằng cờ SO_REUSEADDR, điều này không phổ biến đối với các ứng dụng socket TCP.

Thông thường, SO_REUSEADDR được sử dụng cho một trong hai điều:

  1. Khi một quá trình đã bị rơi, bị giết, hoặc buộc phải khởi động lại mà không nhận được một cơ hội để đóng socket của nó. Hoặc quá trình đã thoát nhưng socket (hoặc ổ cắm kết nối con) vẫn ở trạng thái FIN_WAIT hoặc FIN_WAIT2. Quá trình thứ hai có thể mở ổ cắm mà không nhận được mã lỗi "đã được sử dụng". Tôi đã đọc một vài bài đăng trên S.O. cho thấy đây là phương pháp hay nhất cho các ổ cắm TCP.

  2. Cùng một chương trình máy chủ được chia đôi hoặc chạy đồng thời nhiều lần. Điều này cho phép cân bằng tải mà không có chương trình máy chủ được viết để sử dụng các luồng. Thông thường, "trường hợp khác" của chương trình nghe trên socket sẽ chấp nhận các kết nối đến trong khi đầu tiên đang bận với một kết nối khác.

Về câu hỏi thứ hai, điều dễ nhất là không sử dụng SO_REUSEADDR. Nếu bạn lo ngại rằng có thể có một ứng dụng lừa đảo cố gắng sử dụng SO_REUSADDR, thì ứng dụng của bạn có thể sử dụng SO_EXCLUSIVEADDRUSE. (Một lá cờ, mà về cơ bản nói, "không cho phép các ứng dụng khác để mở cùng một cổng với SO_REUSEADDR.)

+0

Cảm ơn, tôi nghĩ rằng lá cờ giống hệt với cờ UNIX cùng tên. MSDN đã khai sáng: http: //msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx – Olson

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