1. 程式人生 > >通俗介紹TCP三次握手四次揮手

通俗介紹TCP三次握手四次揮手

一直都知道 TCP 建立連線時需要三次握手,釋放連線時需要四次揮手,也大概能說出整個過程,但是一直對其中的設計思想理解不深,停留在“只可意會,不可言傳”的階段。這次寫一篇部落格嘗試將其中的思想表達出來。

TCP 建連三次握手

首先解釋一下每個步驟的作用:
1、a 時刻,A 準備就緒,傳送 SYN 包給 B,嘗試建立連線
2、b 時刻,B 收到 A 發來的 SYN 包,知道 A 要請求建連,回 SYN ACK 包,告訴 A 自己收到了建連請求,可以建連了
3、c 時刻,A 收到了 B 的回覆,知道 B 準備好了,鏈路通暢,可以傳送資料了。回  ACK 告知 B 收到了 B 的回覆,下面要開始傳送該資料了
4、d 時刻,B 收到了 A 的回覆,知道 A 接下來要發資料了。至此,AB 雙方都確認整個鏈路已經可靠了,接下來可以傳送資料了。

為什麼要多次確認呢?為什麼不可以 A 上來就直接傳送資料給 B 呢?
這裡首先要明確一點,TCP 是傳輸層的協議,是建立在物理層、資料鏈路層、網路層之上的協議,而底層的網路是不可靠的,可能路由出問題,可能網關出問題,可能網線出問題,A 沒法保證自己發出來的訊息 B 一定能收到,所以一定要反饋機制,即 ACK,這樣才能在不可靠的網路層智商構建可靠的傳輸層。

類比一下生活中的例子,可以幫助我們理解
示例1,假設我們在火車上打電話,通話質量很差,我們的通話過程可能會是下面這樣:

AB 雙方首先需要確認彼此都能挺到對方的聲音,也就是保證電話通道是可靠的,之後才會開始說正事。如果一上來就直接說正事,可能 A 說完之後 B 根本就沒有聽到。
實際打電話過程中,如果遇到了斷線的情況,雙方可能需要進行多次“握手”確認。

示例2,假設我們給剛認識的人第一次打電話,通話過程可能是下面這樣:

AB 雙方都要確認對方的身份,也就是保證通話是在跟自己人進行,確保電話通道是可靠的,不是跟騙子通話,然後才會開始說正事。如果一上來沒有確認身份,不能保證通道是跟自己人進行的,那直接說出重要的事,很可能就洩漏了機密。

總之,握手過程的最終目的就是保證雙方都準備就緒,通路是可靠的,之後就可以放心的傳送重要資料了。

那為什麼一定是三次呢,為什麼不是兩次或者四次呢?
先來說一下為什麼不能少。
一次可以嗎?不可以。設想一下,A 對 B 說:我要給你發資料。然後不等 B 的回覆,接下來就開始發資料了。這時候根本不能保證 B 已經準備好了,那 A 發出來的資料就沒法保證 B 一定能收到。聯想生活中的場景,你隔著很遠的距離向對方喊話:我要把蘋果扔給你。然後不關心對方有沒有聽到,就直接扔了,那最終的結果通常就是對方接不到蘋果,因為對方可能根本沒有收到訊息。
兩次可以嗎?不可以。設想一下,A 對 B 說:我要給你發資料,然後 B 收到訊息後給 A 回覆:收到,A 在收到 B 的回覆後開始傳送資料。這時候 A 端是可以準備就緒的,但是 B 端不知道 A 端當前的狀態。因為 B 在收到 A 的訊息的時候,可能已經過去了很長時間,B 在回訊息的時候,A 可能已經不線上了,此時 B 是不能直接發資料的。如果 A 再給 B 回一個 ACK,B 就可以確認當前鏈路狀態了,這就變成了三次握手。

接下來說一下為什麼不是四次。既然三次已經可以保證建立可靠通訊,就不需要額外的一次互動了。

下面是幾個生活中相關的示例:

TCP 斷鏈四次揮手

1、a 時刻,A 向 B 發出 FIN 包,表示自己沒有資料要傳送了
2、b 時刻,B 收到 FIN 包,回覆 FIN ACK,表示收到了 A 的 FIN 包,不會再接收 A 的資料了
3、B 在發完 FIN ACK 後,可能還有資料要發給 A,這個資料是不能停止傳送的,有資料還是需要繼續傳送
4、d 時刻,B 發完了資料,也發出 FIN 包,告訴 A 自己的資料發完了,不再發送資料了
5、e 時刻,A 收到了 B 的 FIN 包,知道 B 也沒有資料要傳送了,回覆 FIN ACK。此時,連線可以斷開了

建連只需要互動三次,斷連卻需要四次,這是為什麼呢?其實斷開連線和建立連線還是不一樣的。建連的時候,只要雙方都告知對方自己準備好了就可以,但是斷連的時候,一方提出要斷開連線,不再發資料,另一方不能立即斷開,因為這一方可能還有資料要傳送,直到資料全部發送完成後才能確認斷開。

下面是幾個生活中相關的示例:

以上是對於三次握手、四次揮手的簡單介紹,裡面沒有更詳細的狀態介紹,之後的部落格會介紹,這裡先放兩張圖。

TCP 三次握手

TCP 四次揮手