本文將深入探討 TCP 協議中三次握手、四次揮手的原理,以及其保證可靠傳輸的機制。
一、三次握手:為何是三次,而非兩次?
建立 TCP 連接的過程猶如一場嚴謹的 “對話”,需要經過三次握手才能確保通信雙方的可靠連接。
三次握手的具體流程
第一次握手:客戶端率先向服務端發送帶有 SYN(SEQ=x)標志的數據包,隨后進入 SYN_SEND 狀態,此時客戶端如同一位等待回應的信使,它不清楚服務端的任何狀況。而服務端接收到該數據包后,確認了客戶端具備發送能力,同時也確認自身接收功能正常。
第二次握手:服務端回應客戶端,發送帶有 SYN + ACK (SEQ=y, ACK=x + 1) 標志的數據包,進入 SYN_RECV 狀態。客戶端接收到此數據包后,不僅確認自己的發送和接收功能正常,還確認了服務端的發送和接收同樣正常。
第三次握手:客戶端再次向服務端發送帶有 ACK (ACK=y + 1) 標志的數據包,隨后客戶端和服務端雙雙進入 ESTABLISHED 狀態,至此三次握手完成,雙方可以開啟數據傳輸之旅。此時,雙方都明確彼此的發送和接收功能均處于正常狀態。
兩次握手的缺陷
網絡環境復雜多變,丟包問題時有發生。若僅進行兩次握手,當第二次握手時服務端發給客戶端的確認報文丟失,就會出現嚴重問題。此時,服務端認為連接已建立并準備接收和處理數據,而客戶端由于未收到確認報文,不會發送數據,并且會忽略服務端后續的數據。然而,若采用三次握手,即便客戶端發送的確認報文丟失,服務端在一段時間內未接收到,就會重新發起第二次握手,從而保障連接建立的可靠性。
二、四次揮手:為什么斷開連接需要4次?
當數據傳輸任務完成,TCP 連接的斷開同樣需要遵循嚴謹的流程,即四次揮手。
四次揮手的詳細步驟
第一次揮手:客戶端向服務端發送帶有 FIN(SEQ=x)標志的數據包,表明客戶端到服務端的數據傳送即將結束,隨后客戶端進入 FIN - WAIT - 1 狀態。這就像是客戶端告知服務端:“我這邊的數據已經發送完畢啦”。
第二次揮手:服務端收到客戶端的 FIN 數據包后,向客戶端發送 ACK (ACK=x + 1)標志的數據包,確認收到客戶端的斷開請求,服務端進入 CLOSE - WAIT 狀態,客戶端則進入 FIN - WAIT - 2 狀態。此時,服務端可能還有數據需要繼續發送。
第三次揮手:當服務端完成剩余數據的發送后,向客戶端發送 FIN (SEQ=y) 標志的數據包,請求關閉連接,自身進入 LAST - ACK 狀態。這一步相當于服務端回應客戶端:“我這邊的數據也發完了,我們可以斷開連接了”。
第四次揮手:客戶端收到服務端的 FIN 數據包后,發送 ACK (ACK=y + 1) 標志的數據包給服務端,然后進入 TIME - WAIT 狀態。服務端收到 ACK 數據包后進入 CLOSE 狀態。客戶端在 TIME - WAIT 狀態等待 2MSL(最長報文段壽命)后,如果沒有收到其他回復,就可以確認服務端已正常關閉,隨后客戶端也關閉連接。在四次揮手未完成之前,客戶端和服務端仍可繼續傳輸數據。
為什么一定是四次揮手?
TCP 采用全雙工通信模式,允許數據在兩個方向上同時傳輸。因此,任何一方都可以在數據傳送結束后發起連接釋放的通知,待對方確認后進入半關閉狀態。只有當雙方都完成數據傳輸并確認后,才能完全關閉 TCP 連接。至于為何不能將服務端發送的 ACK 和 FIN 合并為一次,變成三次揮手,原因在于服務端收到客戶端斷開連接的請求時,可能還有一些數據尚未發送完畢。此時先回復 ACK,表示已接收到斷開連接的請求,等到數據發送完成后再發送 FIN,以斷開服務端到客戶端的數據傳送。
三、TCP 如何確保可靠傳輸?
為了保障數據在網絡中的可靠傳輸,TCP 采用了一系列精妙的機制。
基于數據塊傳輸
TCP 會將應用數據分割成其認為最適宜發送的數據塊(報文),再傳遞給網絡層。這就好比將一大箱貨物合理地分裝成多個小包裹,以便在復雜的網絡道路上高效運輸,提高傳輸效率。
數據包的排序與去重
TCP 為每個數據包分配一個唯一的序列號,如同給每個小包裹貼上特定的標簽。接收端依據這些序列號對接收到的數據進行排序,并去除重復序列號的數據,從而確保數據的準確性和有序性。
校驗和機制
TCP 會計算并維護首部和數據的檢驗和,這就像是給每個包裹貼上一個質量檢測標簽。若接收到的報文段檢驗和出現差錯,TCP 會果斷丟棄該報文段,并且不確認收到此報文段,以此保證數據的完整性。
重傳機制
基于計時器的重傳(超時重傳):數據包發送出去后,TCP 會啟動一個計時器。若在規定時間內未收到對方的確認應答(ACK),就如同包裹寄出后長時間沒有收到收件人的確認,TCP 會重新發送該數據包。
快速重傳:當接收端發現數據包失序時,會立即向發送端發送重復的 ACK 報文。發送端在收到多個重復的 ACK 后,無需等待計時器超時,就會迅速重傳丟失的數據包,大大提高了重傳的效率。
SACK(選擇性確認):在快速重傳的基礎上,接收端會返回最近收到的報文段的序列號范圍,這樣發送端就能清楚地知道哪些數據包已經成功到達服務器,從而精準地重傳丟失的數據。
D - SACK(重復 SACK):D - SACK 在 SACK 的基礎上更進一步,額外攜帶信息告知發送方哪些數據包被重復接收了,幫助發送方更全面地了解網絡狀況,優化重傳策略。
流量控制
TCP 連接的雙方都設有固定大小的緩沖空間。接收端通過滑動窗口協議,如同調節一扇窗戶的開合程度,只允許發送端發送接收端緩沖區能夠接納的數據量,以此防止數據擁堵,避免數據包丟失。
擁塞控制
TCP 在發送數據時,會充分考慮兩個關鍵因素:接收方的接收能力和網絡的擁塞程度。接收方的接收能力通過滑動窗口來體現,表示接收方還有多少緩沖區可用于接收數據;網絡的擁塞程度則由擁塞窗口表示,這是發送方根據網絡狀況自行維護的一個值,反映了發送方認為可以在網絡中順利傳輸的數據量。發送方發送數據的大小取滑動窗口和擁塞窗口的最小值,這樣既能確保不超過接收方的接收能力,又能避免對網絡造成過度擁塞。
資料:計算機網絡面試必備知識點詳解-CSDN博客