筆記分享:網絡基礎之TCP/IP四次揮手

圖片來源自網絡

“揮手”是爲了終止連接,TCP四次揮手的流程圖如下:

  • 第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態;
    • 客戶端發送報文,完成信號FIN=1,序號seq=u
    • 進入完成FIN_WAIT_1狀態,等待服務端確認
  • 第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態
    • 服務端發送確認報文,確認信號ACK=1,序號=v,確認序號ack=u+1
    • 此時服務端就進入Close-wait狀態,半關閉狀態
    • 此時客戶端就進入FIN-wait狀態,終止等待狀態,等待服務器發送釋放連接報文
    • 這裏有可能服務端還會持續完成數據傳送。因此seq值會改變
  • 第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
    • 服務端發送數據完成報文,完成信號FIN=1,確認信號ACK=1,序號seq=w,確認信號ack=u+1
    • 此時服務端進入最後確認狀態,等待客戶端發送確認
  • 第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。
    • 客戶端確認報文,確認信號ACK=1,序號seq = u+1,確認序號ack=w+1
    • 此時服務端進入關閉狀態
    • 此時客戶端進入TIME-WAIT狀態,時間等待狀態,還未釋放連接,必須經過2*MSL的時間纔會進行釋放。RFC定義爲兩分鐘,而Linux的時間爲30秒
  • 爲什麼會有TIME_WAIT狀態
    • 確保有足夠時間讓對方(上圖爲server端)收到ACK包
    • 避免新舊連接混繞
  • 爲什麼需要四次握手才能斷開連接
    • 因爲全雙工,發送方和接收方都需要FIN報文和ACK報文
  • 服務器出現大量CLOSE_WAIT狀態的原因
    • 對方關閉socker連接,我方忙於讀或寫,沒有及時關閉連接
    • 檢查代碼,特別是釋放資源的代碼
    • 檢查配置,特別是處理請求的線程配置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章