考慮一個父進程完成 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
這使得這個答案很難弄清楚。