CLOSE_WAIT 問題
原因很簡單:TCP 四次揮手問題,發起于 FIN 指令
具體細節,請自行百度
需要注意的是,CLOSE_WAIT 隻存在于 socket 連接配接已經連接配接成功後
錯誤的文章誘導
點名批評下 : http://blog.huoding.com/2016/01/19/488
具體摘錄如下:
了解伺服器端成功建立連接配接過程中的行為
參考文章:
- https://blog.csdn.net/alitech2017/article/details/80922902
- http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html
上面 2 篇文章把伺服器端連接配接過程中的問題,以及 backlog 工作原理見得很清楚了
這裡再簡單複述下過程,見圖:
- 用戶端(53302) 發送 SYN 指令,請求建立連接配接
- 伺服器端(999) 發送 SYN-ACK 指令,應答(socket 到 sync queue)
- 用戶端(53302) 發送 ACK 指令,并認為自己已經連接配接完成
- 伺服器端(999) 收到 ACK 指令後,發現 accept queue 滿,則丢棄 ACK 包
- 伺服器端(999) 重複
,發送 SYN-ACK 指令BackOff (退避算法)
- 伺服器端(999) 一直沒有收到用戶端 ACK 指令的話,最終會發送 RST 指令,關閉連接配接
上述流程中,伺服器端做第 5 部時,用戶端在做下面事情:
- 用戶端(53302) 會開始發送資料 PSH-ACK (因為用戶端認為連接配接已經建立成功)
- 然後因為收不到伺服器端(999) 的 ACK 包,重複
,發送資料 PSH-ACKBackOff (退避算法)
上述圖中沒有的另外一種情況,用戶端認為連接配接已經建立成功後,不發資料,然後被伺服器端(999)最終會發送 RST 指令,關閉連接配接
是以, 伺服器端:
- 要麼收到用戶端發送的 ACK 指令,完成三次握手。 accpet() 函數傳回 socket 對象
- 要麼發送 RST 指令結束連接配接
socket 狀态圖
下圖摘自網絡文章,主要說明下: CLOSE_WAIT 隻可能出現在 ESTABLISHED 狀态後面;且隻有收到 FIN 指令才轉移
結論
- TCP 連接配接建立過程中,伺服器端隻會發送 RST 指令重置連接配接
- backlog 值隻可能讓大量連接配接無法連接配接上伺服器
- CLOSE_WAIT 隻可能出現在 ESTABLISHED 狀态後面;且隻有收到 FIN 指令才轉移
其他
文中提到
BackOff (退避算法)
,這個可能不是 TCP 中的專有名詞,總之表達一個意思, 下次重複發送指令的時間會變長