當沒有綁定偵聽套接字但連線已開啟時取得 EADDRINUSE 的語意是什麼

當沒有綁定偵聽套接字但連線已開啟時取得 EADDRINUSE 的語意是什麼

考慮一個父進程完成 a socket/bind/accept,並將分叉子進程,並打開該套接字以供它們進行通信,同時父進程繼續接受連接。然後該父進程被終止。

現在,另一個進程嘗試在同一連接埠上綁定到父進程綁定到的相同位址,但收到 EADDRINUSE 錯誤。

但是,當您使用 完成此過程時sshd,似乎sshd 能夠重新綁定到已關閉的端口,而在重新啟動視窗期間(sshd 父進程未運行),不同的程式(以不同用戶身份運行)只會獲取 EADDRINUSE。

這背後的語意是什麼?為什麼可以sshd重新綁定,但另一個使用者程序卻不能?

此外,我可以確認netstat -a | grep PORT只有子進程運行期間(當其他進程不能運行時bind)的輸出,唯一的連接是ESTABLISHED一個,沒有處於LISTEN狀態。

答案1

雖然我不理解所有的語義(我要么找錯地方,要么缺少文檔),但我相信在關閉連接後的一定時間內(可能由 設定SO_LINGER),沒有進程可以打開一個具有相同詳細信息的新套接字,除非它們已SO_REUSEADDR設定。

據我了解,這是為了防止有人在連接關閉後重新連接,並且該進程必須處理用於前一個進程的資料包。

man 7 socket沒有記錄這一點,SO_REUSEADDR這使得這個答案很難弄清楚。

相關內容