天天看點

一個 CLOSE_WAIT 問題 - TCP 三次握手原理(備忘)

CLOSE_WAIT 問題

原因很簡單:TCP 四次揮手問題,發起于 FIN 指令

具體細節,請自行百度

需要注意的是,CLOSE_WAIT 隻存在于 socket 連接配接已經連接配接成功後

錯誤的文章誘導

點名批評下 : http://blog.huoding.com/2016/01/19/488

具體摘錄如下:

一個 CLOSE_WAIT 問題 - TCP 三次握手原理(備忘)

了解伺服器端成功建立連接配接過程中的行為

參考文章:

  • https://blog.csdn.net/alitech2017/article/details/80922902
  • http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html

上面 2 篇文章把伺服器端連接配接過程中的問題,以及 backlog 工作原理見得很清楚了

這裡再簡單複述下過程,見圖:

一個 CLOSE_WAIT 問題 - TCP 三次握手原理(備忘)
  1. 用戶端(53302) 發送 SYN 指令,請求建立連接配接
  2. 伺服器端(999) 發送 SYN-ACK 指令,應答(socket 到 sync queue)
  3. 用戶端(53302) 發送 ACK 指令,并認為自己已經連接配接完成
  4. 伺服器端(999) 收到 ACK 指令後,發現 accept queue 滿,則丢棄 ACK 包
  5. 伺服器端(999) 重複

    BackOff (退避算法)

    ,發送 SYN-ACK 指令
  6. 伺服器端(999) 一直沒有收到用戶端 ACK 指令的話,最終會發送 RST 指令,關閉連接配接

上述流程中,伺服器端做第 5 部時,用戶端在做下面事情:

  • 用戶端(53302) 會開始發送資料 PSH-ACK (因為用戶端認為連接配接已經建立成功)
  • 然後因為收不到伺服器端(999) 的 ACK 包,重複

    BackOff (退避算法)

    ,發送資料 PSH-ACK

上述圖中沒有的另外一種情況,用戶端認為連接配接已經建立成功後,不發資料,然後被伺服器端(999)最終會發送 RST 指令,關閉連接配接

是以, 伺服器端:

  • 要麼收到用戶端發送的 ACK 指令,完成三次握手。 accpet() 函數傳回 socket 對象
  • 要麼發送 RST 指令結束連接配接

socket 狀态圖

下圖摘自網絡文章,主要說明下: CLOSE_WAIT 隻可能出現在 ESTABLISHED 狀态後面;且隻有收到 FIN 指令才轉移

一個 CLOSE_WAIT 問題 - TCP 三次握手原理(備忘)

結論

  1. TCP 連接配接建立過程中,伺服器端隻會發送 RST 指令重置連接配接
  2. backlog 值隻可能讓大量連接配接無法連接配接上伺服器
  3. CLOSE_WAIT 隻可能出現在 ESTABLISHED 狀态後面;且隻有收到 FIN 指令才轉移

其他

文中提到

BackOff (退避算法)

,這個可能不是 TCP 中的專有名詞,總之表達一個意思, 下次重複發送指令的時間會變長

繼續閱讀