TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

關於TCP的文章,網上有很多,講“三次握手”和“四次揮手”的文章,頭條裏面也不止10篇。那些文章都很好的詮釋了其原理,但是有些話語都乾澀難懂,自己得反覆的揣摩!

正好,霸哥今天在與朋友交流的時候,又看到有人在問TCP“三次握手”的問題:

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

其實,已經知道朋友肯定就能很快理解這句話的意思,但是還在摸索中的朋友呢?

 

下面霸哥將用自己的方式來講講,這TCP的“三次握手”和“四次揮手”到底是怎麼一回事

 

在很久很久以前.....

面試官:說說什麼是TCP?

程序員:傳輸協議

面試官:UDP也是,那爲什麼不用UDP呢?

程序員:因爲UDP把數據傳輸過去就不管了,就假定接收方一定能接收到,可惜真實的網絡環境不會如此單純,甚至是複雜、殘酷的。

在網絡環境中無時無刻出現着丟包、阻塞、亂序的情況,一個不小心,數據可能就傳輸不到目的地了,這個時候就只能輪到TCP了

面試官:爲什麼TCP就可靠了呢?

程序員:就是因爲它的“三次握手”和“四次揮手”哇!

面試官(邪魅一笑):那你來講講吧!

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

程序員:那您且細聽分說

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

三次握手

程序員:這個“三次握手”就是通信建立鏈接的一個過程,看下圖

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

通俗點講就是:

客戶端:你好,我是客戶端

 

服務端:你好,客戶端,我是服務端

 

客戶端:你好,服務端

也經常把這個過程叫做“請求->響應->響應的響應”

 

面試官:打斷一下,問個問題,爲什麼不是兩次或者四次,非得是三次呢?

程序員:嗯,不錯,是個稱職的面試官!

試想一下,客戶端發送一個連接,由於丟包、超時,或是服務端根本就不想建立連接,那這個時候客戶端怎麼辦?

客戶端並不能知道結果,就只有重複的發送連接請求,雖然這個時候服務端接收到了,但客戶端仍不知道這事,只能繼續發請求。

此時此刻,服務端接收了客戶端的請求,當然知道了客戶端的存在,如果服務端不同意建立連接,客戶端重試幾次後就會放棄,沒問題。

如果服務端願意建立連接呢?這個時候就會發送響應給客戶端(好了,你別叫喚了,客戶端我知道你了)

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

到了這一步,就已經進行了兩次握手!理論上,這個時候已經可以進行連接了,但是問題來了:

因爲對於服務端來說,這個響應的過程也可能會丟包,不一定會達到客戶端,甚至客戶端完全掛了都是可能的。

對於另外的情況,在第一次握手的時候,由於網絡問題,客戶端向服務端發送了多個建立連接的請求,假設其中某一個建立成功,做了簡單的通信,然後結束了連接,本來很正常,但是另外一些請求由於網絡的延遲又到了服務端,服務端會認爲這是一個正常的請求,接下來又建立連接。

 

因此兩次握手會有着種種問題。

爲了保證服務端的響應能正確接收,客戶端還是需要告訴給服務端,我收到了服務端的響應,也就是給服務端一個“響應的響應”,這樣就是三次握手了

面試官:要是這個“響應的響應”要是也出現了丟包等問題沒有送到呢?

程序員:你存心找麻煩的吧?那照你這樣說你就是手握爛了,也沒辦法保證消息100%可靠。三次握手,保證服務端、客戶端雙方都確認了對方存在就足夠了。

 

福利提醒:看我左側主頁欄目,免費福利任你去領←←←

 

四次揮手

面試官:嗯,不錯,來說說“四次揮手”又是什麼吧!

程序員:建立完連接後就可以傳輸數據了,傳輸完成後則需要四次揮手來告別,過程看下圖

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

面試官:這你TMD沒有上一張清晰啊!

程序員:哎呀~面試時間有限,將就着看看啦!

通俗來講就是...

客戶端:服務端啊,我要和你拜拜了

服務端:好的,我知道了

這個時候,客戶端說了拜拜,也不會向服務端發送數據了,這個時候服務端是否能馬上關閉呢?

不可以!因爲服務端可能還沒處理完相應的事情,所以還是要發送數據的,這個時候的狀態爲等待關閉的狀態,當處理完後需要繼續下面步驟。

服務端:客戶端,我也要和你說拜拜了

客戶端:拜拜,滾吧

TCP爲何要進行“三次握手”和“四次揮手”?百度都沒這麼詳細

 

程序員:其實在這裏也會存在一些問題,當客戶端說“拜拜”,服務端說“知道了”,這兩次是沒什麼問題的。

但是當客戶端說“拜拜”之後就直接奪門而出,這樣就出問題了,因爲服務端還沒說“知道了”,就算已經說了“知道了”,客戶端也可能已經走了。

這個時候爲了解決這些問題,TCP協議還有幾個狀態來處理這些問題,就如上面看的狀態圖:

當客戶端說“拜拜”,就進入 FIN_WAIT_1 的狀態,服務端收到“拜拜”的消息後,發送“知道了”,然後就進入 CLOSE_WAIT 的狀態。

當客戶端接收到“知道了”,進入FIN_WAIT_2,過一段時間,客戶端也接收到了“客戶端,我也要和你說拜拜了”,客戶端就應該發送“拜拜,滾吧”,說完這句話已經就可以走了。

 

但是客戶端發送的消息沒發送成功,服務端只能重複發送“我也要和你說拜拜”,可惜的客戶端已經走了,永遠不會給你響應。

由於存在這種問題,TCP協議要求客戶端在離開之前先等待一會會,這個等待的時間叫TIME_WAIT,這個TIME_WAIT還有另外一個作用,如果客戶端說完“拜拜”之後還需要等待一段時間,如果不等待就會直接釋放端口。

在前面一次連接客戶端說完“拜拜”就走了,服務端不知道,不停的回覆“知道了”,這時候一個新的客戶端連接了,這新客戶端接收到了“知道了”這是不是就特別混亂了?

所以這TIME_WAIT就特別重要了,它可以保證讓遲來的TCP報文段有足夠的時間被識別和丟棄。連接結束了,網絡中的延遲報文也應該被丟棄掉,以免影響立刻建立的新連接。

看懂了就點個贊加個關注吧!

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