TCP的TIME_WAIT和CLOSE_WAIT

1.四次揮手服務端和客戶端的狀態:

  • 主動關閉連接的一方,調用 close ();協議層發送 FIN 包;
  • 被動關閉的一方收到 FIN 包後,協議層回覆 ACK;然後被動關閉的一方,進入 CLOSE_WAIT 狀態,主動關閉的一方等待對方關閉,則進入 FIN_WAIT_2 狀態;此時,主動關閉的一方等待被動關閉一方的應用程序,調用 close 操作;
  • 被動關閉的一方在完成所有數據發送後,調用 close () 操作;此時,協議層發送 FIN 包給主動關閉的一方,等待對方的 ACK,被動關閉的一方進入 LAST_ACK 狀態;
  • 主動關閉的一方收到 FIN 包,協議層回覆 ACK;此時,主動關閉連接的一方,進入 TIME_WAIT 狀態;而被動關閉的一方,進入 CLOSED 狀態;
  • 等待 2MSL 時間,主動關閉的一方,結束 TIME_WAIT,進入 CLOSED 狀態;

在這裏插入圖片描述

2.總結上面的過程,得出一次 socket 關閉操作:

  • 主動關閉連接的一方 – 也就是主動調用 socket 的 close 操作的一方,最終會進入 TIME_WAIT 狀態;
  • 被動關閉連接的一方,有一箇中間狀態,即 CLOSE_WAIT,因爲協議層在等待上層的應用程序,主動調用 close 操作後才主動關閉這條連接;
  • TIME_WAIT 會默認等待 2MSL(2 倍的max segment lifetime) 時間後,才最終進入 CLOSED 狀態;
  • 在一個連接沒有進入 CLOSED 狀態之前,這個連接是不能被重用的!

3.TIME_WAIT 並不可怕,CLOSE_WAIT 纔可怕,因爲 CLOSE_WAIT 很多,表示說:

  • 要麼是你的應用程序寫的有問題,沒有合適的關閉 socket
  • 要麼是說,你的服務器 CPU 處理不過來(CPU 太忙)或者你的應用程序一直睡眠到其它地方 (鎖,或者文件 I/O 等等),你的應用程序獲得不到合適的調度時間,造成你的程序沒法真正的執行 close 操作

4.TIME_WAIT 有什麼用?

  • 防止前一個連接上延遲的數據包或者丟失重傳的數據包,被後面複用的連接錯誤的接收
  • 確保連接方能在時間範圍內,關閉自己的連接

5.爲什麼 TIME_WAIT 狀態 停留 2MSL(max segment lifetime)時間?

  • 爲了防止上次連接的報文數據影響到下次的連接,有充分的的時間處理上次連接的報文信息。

  • 客戶端最後發的 ACK 可能會丟失,此時服務器端會重新發送 FIN,若此時客戶端處於 closed,會響應 rst (rst 段標識復位,用來異常的關閉連接) 而不是 ACK。因此客戶端是 TIME_WAIT 狀態,不是 closed。

6.什麼原因造成出現大量CLOSE_WAIT?

  • 出現大量 close_wait 的現象主要原因是某種情況下對方關閉了 socket 鏈接,但是我方忙與讀或者寫,沒有關閉連接。

7.什麼原因造成大量 TIME_WAIT

  • 在高併發短連接的 TCP 服務器上,當服務器處理完請求後立刻主動正常關閉連接。這個場景下會出現大量 socket 處於 TIME_WAIT 狀態。如果客戶端的併發量持續很高,此時部分客戶端就會顯示連接不上。

8.如何處理大量CLOSE_WAIT?

  • 給每一個 socket 設置一個時間戳 last_update,每接收或者是發送成功數據,就用當前時間更新這個時間戳。定期檢查所有的時間戳,如果時間戳與當前時間差值超過一定的閾值,就關閉這個 socket。
  • 使用一個 Heart-Beat 線程,定期向 socket 發送指定格式的心跳數據包,如果接收到對方的 RST 報文,說明對方已經關閉了 socket,那麼我們也關閉這個 socket。

【Java 面試那點事】

這裏致力於分享 Java 面試路上的各種知識,無論是技術還是經驗,你需要的這裏都有!

這裏可以讓你【快速瞭解 Java 相關知識】,並且【短時間在面試方面有跨越式提升】

面試路上,你不孤單!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章