綁定通訊端(binding a socket)
在一家店能接受電話訂購之前,它得占下一個顧客會撥的電話號碼。綁定通訊端就是占下那個號碼。它告訴作業系統:這個通訊端應該擁有這個特定的本機位址與連接埠,好讓抵達該位址與埠的流量被交給我。沒有綁定,通訊端就沒有別人能瞄準的固定本機身分。
程式碼裡你呼叫 bind(fd, address),這個位址把一個本機 IP(常用 0.0.0.0 代表每個網路介面,或 127.0.0.1 只代表環回)和一個連接埠號配成一對。核心檢查該埠沒有被以衝突的方式占用,然後把它保留給你的通訊端。伺服器幾乎總是明確地綁定,因為用戶端必須事先知道去哪找它們——網頁伺服器綁 TCP port 443,DNS 伺服器綁 UDP port 53。用戶端通常不呼叫 bind;當它們 connect 時,作業系統會改為自動指派一個臨時來源埠,所以對它們來說明確的 bind 是不必要的。
為什麼重要:bind 是把一個空白通訊端變成可觸及端點的步驟,也是你決定服務觸及範圍的地方。綁到 0.0.0.0,整個網路都能連入;綁到 127.0.0.1,只有本機能。兩個實務上的危險:綁到 1024 以下的特權埠通常需要管理員權限;而試圖綁另一個行程已占用的埠會以「address already in use(位址已在使用中)」錯誤失敗——這在伺服器剛重啟後特別常見,因為先前的連線可能還滯留在 TIME-WAIT 狀態(SO_REUSEADDR 選項是常見的解法)。
一台伺服器執行 bind(fd, {0.0.0.0, 8080})。從此之後,網路上任何連到本主機 8080 埠的用戶端都會被導向那個通訊端。若它改用 {127.0.0.1, 8080},就只有同一機器上的程式能觸及它。
bind 同時選定伺服器應答所用的本機介面與連接埠。
重啟後立刻出現「address already in use」通常不代表別的程式偷了埠——而是你自己的舊連線還在 TIME-WAIT。在 bind 之前設定 SO_REUSEADDR,就能立即重新綁定。