【TCP/IP】三次握手過程及原因

三次握手都做什麼?

三次握手 建立起 TCP連接 的 reliable,分配初始序列號資源,在相互確認之後開始數據的傳輸。有 主動打開(一般是client) 和 被動打開(一般是server)。

TCP使用3次握手建立一條連接,該握手初始化了傳輸可靠性以及數據順序性必要的信息,這些信息包括兩個方向的初始序列號,確認號由初始序列號生成,使用3次握手是因爲3次握手已經準備好了傳輸可靠性以及數據順序性所必要的信息,該握手的第3次實際上並不是需要單獨傳輸的,完全可以和數據一起傳輸。詳細過程如下所示:

第一步,Client會進入SYN_SENT狀態,併發送Syn 消息給Server端,SYN標誌位在此場景下被設置爲1,同時會帶上Client這端分配好的Seq號,這個序列號是一個U32的整型數,該數值的分配是根據時間產生的一個隨機值,通常情況下每間隔4ms會加1。除此之外還會帶一個MSS,也就是最大報文段長度,表示Tcp傳往另一端的最大數據塊的長度。

第二步,Server端在收到,Syn消息之後,會進入SYN_RCVD狀態,同時返回Ack消息給Client,用來通知Client,Server端已經收到SYN消息並通過了確認。這一步Server端包含兩部分內容,一部分是回覆Client的Syn消息,其中ACK=1,Seq號設置爲Client的Syn消息的Seq數值+1;另一部分是主動發送Sever端的Syn消息給Client,Seq號碼是Server端上面對應的序列號,當然Syn標誌位也會設置成1,MSS表示的是Server這一端的最大數據塊長度。

第三步,Client在收到第二步消息之後,首先會將Client端的狀態從SYN_SENT變換成ESTABLISHED,此時Client發消息給Server端,這個方向的通道已經建立成功,Client可以發送消息給Server端了,Server端也可以成功收到這些消息。其次,Client端需要回復ACK消息給Server端,消息包含ACK狀態被設置爲1,Seq號碼被設置成Server端的序列號+1。(備註:這一步往往會與Client主動發起的數據消息,合併到一起發送給Server端。)

第四步,Server端在收到這個Ack消息之後,會進入ESTABLISHED狀態,到此時刻Server發向Client的通道連接建立成功,Server可以發送數據給Client,TCP的全雙工連接建立完成。


爲什麼需要三次握手?

TCP的連接因爲是全雙工的,也就是Client和Server兩端,發送消息兩個方向的連接都要建立成功。如果要保證雙向連接都成功的話,三次通信是最少的次數了。大於三次的話,後面的次數通信就沒有必要了,是在浪費資源。

二次的話,會怎麼樣,可不可以呢?答案是不可以,我們來看下,下面的場景。

在談論這個之前,我們先要知道TCP是基於IP協議的,而IP協議是有路由的,IP協議不能夠保證先發送的數據先到達,這當中依賴於IP協議底層的網絡質量,以及Client與Server之間的路由跳數。

Client在發送完Syn消息1,這裏稱作Syn1之後,假設因爲網絡原因,Syn1並沒有到達Server端,這個時候Client端已經超時,Client之後重新發起SYN消息,這裏稱作Syn2。結果由於網絡原因Syn2先到答Server,Server於是與Client基於Syn2建立了連接,結果沒過多久Syn1又到達了Server,Server於是關掉了Syn2建立的那條連接,又重新建立了一條連接。對於Client來說新建立的這條連接是早就過時的,所以Client不會在這條連接上發送任何數據,這就導致了Server端長時間收不到數據,Client新的連接被斷掉了。

三次握手失敗了會怎麼樣?

這裏要看是在那個階段失敗的,Client在發送SYN之後沒有收到ACK消息,Client會進行重傳,第一次重傳時間5.5-6s之間,第二次重傳會是24s,不成功還會繼續嘗試,伯克利系統在超過75s之後,如果還是不成功,會放棄嘗試連接。(備註:這裏面的重傳時間設置,與底層的定時器設置有過關係,可以參考TCP/IP詳解卷1,這裏不做詳談。)

如果Server沒有收到最後的一次Ack消息,同樣的原理,Server也會進行重傳第二步的Syn+Ack消息。

三次握手的狀態轉換?

TCP的狀態變化圖如下所示,Client和Server的初始狀態都是CLOSED狀態,其中:

Client:

CLOSED-----發送Syn 消息--->SYN_SENT-----收到Server端發回的SYN+ACK--->ESTABLISHED---發送和接收數據-->......

Server:

CLOSED----收到Client端發送過來的SYN消息-->SYN_RCVD-----發送SYN+ACK消息--->SYN_RCVD----收到Client發回來的ACK消息--->ESTABLISHED-----發送和接收數據-->......

其中TCP的三次握手與Scoket的函數對應關係如下所示:

備註:connect時,觸發了連接請求,向服務器發送了SYN J包,這時connect進入阻塞狀態;服務器監聽到連接請求,即收到SYN J包,調用accept函數接收請求向客戶端發送SYN K ,ACK J+1,這時accept進入阻塞狀態;客戶端收到服務器的SYN K ,ACK J+1之後,這時connect返回,並對SYN K進行確認;服務器收到ACK K+1時,accept返回,至此三次握手完畢,連接建立。 --摘自:原文:https://blog.csdn.net/futurewu/article/details/76674016


參考資料:

TCP/IP詳解 卷 I

https://blog.csdn.net/futurewu/article/details/76674016

https://blog.csdn.net/dog250/article/details/6612496

https://blog.csdn.net/varyall/article/details/80348850



灰子做於二零一九年一月二十日。

【原創作品,歡迎分享,請勿轉載,謝謝尊重!!】

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