[轉帖]腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手

腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手
 
http://www.52im.net/thread-1729-1-1.html
 
 

一、引言


網絡編程中TCP協議的三次握手和四次揮手的問題,在面試中是最爲常見的知識點之一。不少讀者都知道「三次」和「四次」,可是若是問深刻一點,他們每每都沒法做出準確回答。

本篇文章嘗試使用動畫圖片的方式,來對這個知識點進行「腦殘式」講解(哈哈),指望讀者們能夠更加簡單、直觀地理解TCP網絡通訊交互的本質。

另外,社區裏的另兩篇文章《理論經典:TCP協議的3次握手與4次揮手過程詳解》、《理論聯繫實際:Wireshark抓包分析TCP 3次握手、4次揮手過程》也是不錯的入門文章,有興趣可一併詳讀之。

友情提示:因本文gif動畫較多,若是您的網速較慢,請耐心等候圖片加載完成哦。

二、關於做者


<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_aa.png 
錢文品(老錢):畢業於華中科技大學計算機科學與技術專業,互聯網分佈式高併發技術十年老兵,目前任掌閱科技資深後端工程師。熟練使用 Java、Python、Golang 等多種計算機語言,開發過遊戲,製做過網站,寫過消息推送系統和MySQL 中間件,實現過開源的 ORM 框架、Web 框架、RPC 框架等。

做者的Github: https://github.com/pyloque

三、系列文章


本文是系列文章中的第1篇,本系列大綱以下:


四、TCP 三次握手:「Say hello !」


TCP 三次握手就比如兩我的在街上隔着50米看見了對方,可是由於霧霾等緣由不能100%確認,因此要經過招手的方式相互肯定對方是否定識本身。

<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_1.gif 

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

可是李四還有點狐疑,向四周看了一看,有沒有可能張三是在看別人呢,他也須要確認一下。因此李四也向張三招了招手(syn),張三看到李四向本身招手後知道對方是在尋求本身的確認,因而也點了點頭擠出了微笑(ack),李四看到對方的微笑後確認了張三就是在向本身打招呼(進入established狀態)。

因而兩人加快步伐,走到了一塊兒,相互擁抱。

<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_2.gif 

咱們看到這個過程當中一共是四個動做,張三招手--李四點頭微笑--李四招手--張三點頭微笑。其中李四連續進行了2個動做,先是點頭微笑(回覆對方),而後再次招手(尋求確認),實際上能夠將這兩個動做合一,招手的同時點頭和微笑(syn+ack)。因而四個動做就簡化成了三個動做,張三招手--李四點頭微笑並招手--張三點頭微笑。這就是三次握手的本質,中間的一次動做是兩個動做的合併。

咱們看到有兩個中間狀態,syn_sent和syn_rcvd,這兩個狀態叫着「半打開」狀態,就是向對方招手了,可是還沒來得及看到對方的點頭微笑。syn_sent是主動打開方的「半打開」狀態,syn_rcvd是被動打開方的「半打開」狀態。客戶端是主動打開方,服務器是被動打開方。

syn_sent: syn package has been sent
syn_rcvd: syn package has been receivedphp


五、握手完成:開始TCP 數據傳輸


TCP 數據傳輸就是兩我的隔空對話,差了一點距離,因此須要對方反覆確認聽見了本身的話。

<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_3.gif 

張三喊了一句話(data),李四聽見了以後要向張三回覆本身聽見了(ack)。

若是張三喊了一句,半天沒聽到李四回覆,張三就認爲本身的話被大風吹走了,李四沒聽見,因此須要從新喊話,這就是tcp重傳。

也有多是李四聽到了張三的話,可是李四向張三的回覆被大風吹走了,以致於張三沒聽見李四的回覆。張三並不能判斷到底是本身的話被大風吹走了仍是李四的回覆被大風吹走了,張三也不用管,重傳一下就是。

既然會重傳,李四就有可能同一句話聽見了兩次,這就是「去重」。「重傳」和「去重」工做操做系統的網絡內核模塊都已經幫咱們處理好了,用戶層是不用關心的。

<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_4.gif 

張三能夠向李四喊話,一樣李四也能夠向張三喊話,由於tcp連接是「雙工的」,雙方均可以主動發起數據傳輸。不過不管是哪方喊話,都須要收到對方的確認才能認爲對方收到了本身的喊話。

張三多是個高射炮,一說連說了八句話,這時候李四能夠不用一句一句回覆,而是連續聽了這八句話以後,一塊兒向對方回覆說前面你說的八句話我都聽見了,這就是批量ack。可是張三也不能一次性說了太多話,李四的腦子短期可能沒法消化太多,兩人之間須要有協商好的合適的發送和接受速率,這個就是「TCP窗口大小」。

網絡環境的數據交互同人類之間的對話還要複雜一些,它存在數據包亂序的現象。同一個來源發出來的不一樣數據包在「網際路由」上可能會走過不一樣的路徑,最終達到同一個地方時,順序就不同了。操做系統的網絡內核模塊會負責對數據包進行排序,到用戶層時順序就已經徹底一致了。

六、TCP 四次揮手:「Say goodbye!」


TCP斷開連接的過程和創建連接的過程比較相似,只不過中間的兩部並不老是會合成一步走,因此它分紅了4個動做,張三揮手(fin)——李四傷感地微笑(ack)——李四揮手(fin)——張三傷感地微笑(ack)。

<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_5.gif 

之因此中間的兩個動做沒有合併,是由於tcp存在「半關閉」狀態,也就是單向關閉。張三已經揮了手,但是人尚未走,只是再也不說話,可是耳朵仍是能夠繼續聽,李四呢繼續喊話。等待李四累了,也再也不說話了,超張三揮了揮手,張三傷感地微笑了一下,才完全結束了。

<ignore_js_op>腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手_6.gif 

上面有一個很是特殊的狀態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的基礎知識掌握得比較牢固,高級的知識理解起來就不會太過於吃力。

附錄1:同類文章精選


若是您以爲本系列文章過於基礎,您可直接閱讀如下系列:


《鮮爲人知的網絡編程》系列文章爲高階必讀,該系列目錄以下:


關於移動端網絡特性及優化手段的總結性文章請見:


附錄2:參考資料


TCP/IP詳解 - 第11章·UDP:用戶數據報協議
TCP/IP詳解 - 第17章·TCP:傳輸控制協議
TCP/IP詳解 - 第18章·TCP鏈接的創建與終止
TCP/IP詳解 - 第21章·TCP的超時與重傳
通俗易懂-深刻理解TCP協議(上):理論基礎
通俗易懂-深刻理解TCP協議(下):RTT、滑動窗口、擁塞處理
理論經典:TCP協議的3次握手與4次揮手過程詳解
理論聯繫實際:Wireshark抓包分析TCP 3次握手、4次揮手過程
計算機網絡通信協議關係圖(中文珍藏版)
高性能網絡編程(一):單臺服務器併發TCP鏈接數到底能夠有多少
高性能網絡編程(二):上一個10年,著名的C10K併發鏈接問題
高性能網絡編程(三):下一個10年,是時候考慮C10M併發問題了
高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索
簡述傳輸層協議TCP和UDP的區別
爲何QQ用的是UDP協議而不是TCP協議?
移動端即時通信協議選擇:UDP仍是TCP?
技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)
UDP中一個包的大小最大能多大?
Java新一代網絡編程模型AIO原理及Linux系統AIO介紹
NIO框架入門(一):服務端基於Netty4的UDP雙向通訊Demo演示
NIO框架入門(二):服務端基於MINA2的UDP雙向通訊Demo演示
NIO框架入門(三):iOS與MINA二、Netty4的跨平臺UDP雙向通訊實戰
NIO框架入門(四):Android與MINA二、Netty4的跨平臺UDP雙向通訊實戰
P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介
P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解
P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解
通俗易懂:快速理解P2P技術中的NAT穿透原理
>> 更多同類文章 ……
相關文章
相關標籤/搜索