2012-09-10 100 views
7

我在Windows 7中運行兩個stunnel實例,配置爲偵聽同一個端口,並且它們似乎都在同一個端口上成功偵聽(使用socket()/ bind()/ listen())。這兩種情況下出現的所有調用成功,他們在netstat的出現:兩個進程如何在Windows 7中監聽同一個端口?

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 

第一個聽得到所有傳入的請求。

這與我所有的期望相反。 (我期待EADDRINUSE告訴我這個端口很忙。)所以......

  1. 爲什麼/它是如何工作的?這種行爲在某些情況下有用嗎?
  2. 我不希望一個實例成功運行,如果另一個應用程序要捕獲傳入的請求......我如何使端口獨佔?

回答

7

如果使用標記SO_REUSEADDR打開套接字,這對於TCP套接字應用程序來說並不少見,則可以完成此操作。

通常,SO_REUSEADDR用於以下兩種情況之一:

  1. 當一個進程崩潰,被殺死,或強行重啓沒有得到一個機會來關閉它的插座。或者進程已退出,但套接字(或子連接套接字)仍處於FIN_WAIT或FIN_WAIT2狀態。第二個進程可以打開套接字而不會收到「已在使用中」的錯誤代碼。我讀過幾篇關於S.O的文章。這表明這是TCP套接字的最佳實踐。

  2. 同一個服務器程序要麼分叉要麼同時運行多次。這允許在沒有編寫服務器程序以利用線程的情況下實現負載平衡。通常,在套接字上監聽的程序的「其他實例」將在第一個忙於另一個連接時接受傳入連接。

關於你的第二個問題,最簡單的事情不是使用SO_REUSEADDR。如果您擔心可能會有嘗試使用SO_REUSADDR的流氓應用,那麼您的應用可以使用SO_EXCLUSIVEADDRUSE。 (一個標誌,基本上說,「不允許其他應用程序使用SO_REUSEADDR打開同一個端口)

+0

謝謝,我認爲該標誌與同名的UNIX標誌相同MSDN很有啓發性:http: //msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx – Olson

相關問題