三次握手四次揮手
- 2020 年 6 月 28 日
- 筆記
一直都知道 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 四次揮手