說說TCP為什麼需要三次握手和四次揮手?

林恒發表於2024-04-07

一、三次握手

三次握手(Three-way Handshake)其實就是指建立一個TCP連線時,需要客戶端和伺服器總共傳送3個包

主要作用就是為了確認雙方的接收能力和傳送能力是否正常、指定自己的初始化序列號為後面的可靠性傳送做準備

過程如下:

  • 第一次握手:客戶端給服務端發一個 SYN 報文,並指明客戶端的初始化序列號 ISN(c),此時客戶端處於 SYN_SENT 狀態
  • 第二次握手:伺服器收到客戶端的 SYN 報文之後,會以自己的 SYN 報文作為應答,為了確認客戶端的 SYN,將客戶端的 ISN+1作為ACK的值,此時伺服器處於 SYN_RCVD 的狀態
  • 第三次握手:客戶端收到 SYN 報文之後,會傳送一個 ACK 報文,值為伺服器的ISN+1。此時客戶端處於 ESTABLISHED 狀態。伺服器收到 ACK 報文之後,也處於 ESTABLISHED 狀態,此時,雙方已建立起了連線

上述每一次握手的作用如下:

  • 第一次握手:客戶端傳送網路包,服務端收到了 這樣服務端就能得出結論:客戶端的傳送能力、服務端的接收能力是正常的。
  • 第二次握手:服務端發包,客戶端收到了 這樣客戶端就能得出結論:服務端的接收、傳送能力,客戶端的接收、傳送能力是正常的。不過此時伺服器並不能確認客戶端的接收能力是否正常
  • 第三次握手:客戶端發包,服務端收到了。 這樣服務端就能得出結論:客戶端的接收、傳送能力正常,伺服器自己的傳送、接收能力也正常

透過三次握手,就能確定雙方的接收和傳送能力是正常的。之後就可以正常通訊了

為什麼不是兩次握手?

如果是兩次握手,傳送端可以確定自己傳送的資訊能對方能收到,也能確定對方發的包自己能收到,但接收端只能確定對方發的包自己能收到 無法確定自己發的包對方能收到

並且兩次握手的話, 客戶端有可能因為網路阻塞等原因會傳送多個請求報文,延時到達的請求又會與伺服器建立連線,浪費掉許多伺服器的資源

二、四次揮手

tcp終止一個連線,需要經過四次揮手

過程如下:

  • 第一次揮手:客戶端傳送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處於 FIN_WAIT1 狀態,停止傳送資料,等待服務端的確認
  • 第二次揮手:服務端收到 FIN 之後,會傳送 ACK 報文,且把客戶端的序列號值 +1 作為 ACK 報文的序列號值,表明已經收到客戶端的報文了,此時服務端處於 CLOSE_WAIT狀態
  • 第三次揮手:如果服務端也想斷開連線了,和客戶端的第一次揮手一樣,發給 FIN 報文,且指定一個序列號。此時服務端處於 LAST_ACK 的狀態
  • 第四次揮手:客戶端收到 FIN 之後,一樣傳送一個 ACK 報文作為應答,且把服務端的序列號值 +1 作為自己 ACK 報文的序列號值,此時客戶端處於 TIME_WAIT狀態。需要過一陣子以確保服務端收到自己的 ACK 報文之後才會進入 CLOSED 狀態,服務端收到 ACK 報文之後,就處於關閉連線了,處於 CLOSED 狀態

四次揮手原因

服務端在收到客戶端斷開連線Fin報文後,並不會立即關閉連線,而是先傳送一個ACK包先告訴客戶端收到關閉連線的請求,只有當伺服器的所有報文傳送完畢之後,才傳送FIN報文斷開連線,因此需要四次揮手

三、總結

一個完整的三次握手四次揮手如下圖所示:

參考文獻

  • https://zhuanlan.zhihu.com/p/53374516
  • https://segmentfault.com/a/1190000020610336

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。

說說TCP為什麼需要三次握手和四次揮手?

相關文章