天天看點

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

TCP三向交握和四次揮手的問題在面試中是最為常見的考點之一。很多讀者都知道三次和四次,但是如果問深入一點,他們往往都無法作出準确回答。

本篇嘗試使用動畫來對這個知識點進行講解,期望讀者們可以更加簡單地地了解TCP互動的本質。

TCP 三次握手

TCP 三次握手就好比兩個人在街上隔着50米看見了對方,但是因為霧霾等原因不能100%确認,是以要通過招手的方式互相确定對方是否認識自己。

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

張三首先向李四招手(syn),李四看到張三向自己招手後,向對方點了點頭擠出了一個微笑(ack)。張三看到李四微笑後确認了李四成功辨認出了自己(進入estalished狀态)。

但是李四還有點狐疑,向四周看了一看,有沒有可能張三是在看别人呢,他也需要确認一下。

是以李四也向張三招了招手(syn),張三看到李四向自己招手後知道對方是在尋求自己的确認,于是也點了點頭擠出了微笑(ack),李四看到對方的微笑後确認了張三就是在向自己打招呼(進入established狀态)。

于是兩人加快步伐,走到了一起,互相擁抱。

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

我們看到這個過程中一共是四個動作,張三招手--李四點頭微笑--李四招手--張三點頭微笑。

其中李四連續進行了2個動作,先是點頭微笑(回複對方),然後再次招手(尋求确認),實際上可以将這兩個動作合一,招手的同時點頭和微笑(syn+ack)。

于是四個動作就簡化成了三個動作,張三招手--李四點頭微笑并招手--張三點頭微笑。這就是三次握手的本質,中間的一次動作是兩個動作的合并。

我們看到有兩個中間狀态,syn_sent和syn_rcvd,這兩個狀态叫着「半打開」狀态,就是向對方招手了,但是還沒來得及看到對方的點頭微笑。

syn_sent是主動打開方的「半打開」狀态,syn_rcvd是被動打開方的「半打開」狀态。用戶端是主動打開方,伺服器是被動打開方。

syn_sent: syn package has been sent

syn_rcvd: syn package has been received

TCP 資料傳輸

TCP 資料傳輸就是兩個人隔空對話,差了一點距離,是以需要對方反複确認聽見了自己的話。

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

張三喊了一句話(data),李四聽見了之後要向張三回複自己聽見了(ack)。

如果張三喊了一句,半天沒聽到李四回複,張三就認為自己的話被大風吹走了,李四沒聽見,是以需要重新喊話,這就是tcp重傳。

也有可能是李四聽到了張三的話,但是李四向張三的回複被大風吹走了,以至于張三沒聽見李四的回複。

張三并不能判斷究竟是自己的話被大風吹走了還是李四的回複被大風吹走了,張三也不用管,重傳一下就是。

既然會重傳,李四就有可能同一句話聽見了兩次,這就是「去重」。「重傳」和「去重」工作作業系統的網絡核心子產品都已經幫我們處理好了,使用者層是不用關心的。

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

張三可以向李四喊話,同樣李四也可以向張三喊話,因為tcp連結是「雙工的」,雙方都可以主動發起資料傳輸。不過無論是哪方喊話,都需要收到對方的确認才能認為對方收到了自己的喊話。

張三可能是個高射炮,一說連說了八句話,這時候李四可以不用一句一句回複,而是連續聽了這八句話之後,一起向對方回複說前面你說的八句話我都聽見了,這就是批量ack。

但是張三也不能一次性說了太多話,李四的腦子短時間可能無法消化太多,兩人之間需要有協商好的合适的發送和接受速率,這個就是「TCP視窗大小」。

網絡環境的資料互動同人類之間的對話還要複雜一些,它存在資料包亂序的現象。

同一個來源發出來的不同資料包在「網際路由」上可能會走過不同的路徑,最終達到同一個地方時,順序就不一樣了。

作業系統的網絡核心子產品會負責對資料包進行排序,到使用者層時順序就已經完全一緻了。

TCP 四次揮手

TCP斷開連結的過程和建立連結的過程比較類似,隻不過中間的兩部并不總是會合成一步走,是以它分成了4個動作,張三揮手(fin)——李四傷感地微笑(ack)——李四揮手(fin)——張三傷感地微笑(ack)。

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

之是以中間的兩個動作沒有合并,是因為tcp存在「半關閉」狀态,也就是單向關閉。

張三已經揮了手,可是人還沒有走,隻是不再說話,但是耳朵還是可以繼續聽,李四呢繼續喊話。等待李四累了,也不再說話了,超張三揮了揮手,張三傷感地微笑了一下,才徹底結束了。

跟着動畫學習 TCP 三次握手和四次揮手TCP 三次握手TCP 資料傳輸TCP 四次揮手總結

上面有一個非常特殊的狀态time_wait,它是主動關閉的一方在回複完對方的揮手後進入的一個長期狀态,這個狀态标準的持續時間是4分鐘,4分鐘後才會進入到closed狀态,釋放套接字資源。不過在具體實作上這個時間是可以調整的。

它就好比主動分手方要承擔的責任,是你提出的要分手,你得付出代價。這個後果就是持續4分鐘的time_wait狀态,不能釋放套接字資源(端口),就好比守寡期,這段時間内套接字資源(端口)不得回收利用。

它的作用是重傳最後一個ack封包,確定對方可以收到。因為如果對方沒有收到ack的話,會重傳fin封包,處于time_wait狀态的套接字會立即向對方重發ack封包。

同時在這段時間内,該連結在對話期間于網際路由上産生的殘留封包(因為路徑過于崎岖,資料封包走的時間太長,重傳的封包都收到了,原始封包還在路上)傳過來時,都會被立即丢棄掉。

4分鐘的時間足以使得這些殘留封包徹底消逝。不然當新的端口被重複利用時,這些殘留封包可能會幹擾新的連結。

4分鐘就是2個MSL,每個MSL是2分鐘。MSL就是maximium segment lifetime——最長封包壽命。這個時間是由官方RFC協定規定的。至于為什麼是2個MSL而不是1個MSL,我還沒有看到一個非常滿意的解釋。

四次揮手也并不總是四次揮手,中間的兩個動作有時候是可以合并一起進行的,這個時候就成了三次揮手,主動關閉方就會從fin_wait_1狀态直接進入到time_wait狀态,跳過了fin_wait_2狀态。

總結

TCP狀态轉換是一個非常複雜的過程,本文僅對一些簡單的基礎知識點進行了類比講解。關于TCP的更多知識還需要讀者去搜尋相關技術文章進入深入學習。如果讀者對TCP的基礎知識掌握得比較牢固,進階的知識了解起來就不會太過于吃力。

原文釋出時間為:2018-07-25

本文作者: 高效運維

本文來自雲栖社群合作夥伴“

高效運維

”,了解相關資訊可以關注“