TCP協議簡析

OSI七層模型與TCP/IP五層模型

OSI(Open System Interconnect),即開放式系統互聯模型是ISO(國際標準化組織)組織在1985年發佈的網絡模型,其結構以下:html

image-20190503131546100

其中的表示層負責提供各類用於應用層數據的編碼和轉換功能, 會話層負責創建、管理和終止表示層實體之間的通訊會話. 這兩層在TCP/IP模型中整合到了應用層.因此咱們經常使用的TCP/IP模型通常只討論5層:算法

image-20190503131508854

能夠看到從應用層發出的數據,每通過一層都會添加上該層特有的header,終端收到數據包以後又會一層層解除頭部拿到原始數據:緩存

圖片摘自阮一峯的博客 http://www.ruanyifeng.com/blo...

net協議

物理層

物理層, 爲數據端設備提供傳送數據的通路。能夠雙向通訊,爲數據傳輸提供可靠的環境。對應咱們的網線、光纖(物理設備)。網絡

這一層不詳細展開了,只說下物理層通訊原理的一個重要概念:併發

  • 單工:單向通道,只能單向通訊。好比廣播。
  • 半雙工:雙向通道,但同一時間點只能一方通訊。好比對講機。
  • 全雙工:雙向通道,相互通訊。互不干擾。好比:電話。

數據鏈路層

數據鏈路層在兩個網絡實體之間提供數據鏈路鏈接的建立、維持和釋放管理。tcp

數據鏈路層只負責數據的封裝成禎和透明傳輸,不保證禎的可靠性,可靠性是tcp協議實現的post

數據鏈路層職責:大數據

  • 封裝成幀編碼

    將網絡層交付下來的ip數據報的先後添加首部和尾部,封裝成幀。首部和尾部的重要做用是進行幀定界。爲了提升傳輸效率,須要儘可能增大數據部分的長度,可是每一個鏈路層協議都規定了幀數據部分的長度上限,最大傳輸單元MTU(Maximum Transfer Unit)。當數據是可打印的ASCII碼,幀定界能夠用特殊的幀定界符SOH(Start of Header)(00000001)和EOT(End of Transmission)(00000100)spa

    image-20190503134026958
    幀的最大長度爲1522字節,其中1500字節是payload:

    圖片摘自阮一峯的博客 http://www.ruanyifeng.com/blo...

    net_package

  • 透明傳輸
  • 傳輸的數據中任何8比特的組合不容許和幀定界的控制字符比特同樣,不然會出現幀定界錯誤。文本文件不會產生這樣的問題,能夠實現透明傳輸。可是若是是二進制文件,可能會找到錯誤的幀邊界。解決方法是採用字節填充。在SOH和EOT的前面加上轉義字符ESC(1B),若是數據中存在轉義字符,就在轉義字符前插入個轉義字符(11011)
  • 差錯控制
    使用循環冗餘檢驗CRC(Cyclic Redundancy Check),添加幀檢驗序列FCS(Frame Check Sequence)

    差錯校驗保證傳遞過來的幀無差錯,可是數據鏈路層不提供可靠服務,仍是存在幀丟失、幀重複、幀失序的問題

網絡層

網絡層提供路由和尋址的功能,使兩終端系統可以互連且決定最佳路徑,並具備必定的擁塞控制和流量控制的能力。

網絡層常見協議有IP,ICMP,OSPF,EIGRP,IGMP等

傳輸層

常見的協議有TCP,UDP等

TCP 是一種面向鏈接的協議,它給用戶進程提供可靠的全雙工的字節流。確保數據包的可靠,有序,以及支持流量控制。

一個TCP包最長1480字節,payload大概1460左右.所以,一條1500字節的信息須要兩個 TCP 數據包。HTTP/2 協議的一大改進, 就是壓縮 HTTP 協議的頭信息,使得一個 HTTP 請求能夠放在一個 TCP 數據包裏面,而不是分紅多個,這樣就提升了速度。

tcp和udp的區別

  • tcp是面向鏈接的,也就是說,在收發數據前,必須和對方創建可靠的鏈接。upd是無鏈接的,傳輸數據以前源端和終端不創建鏈接, 當它想傳送時就簡單地去抓取來自應用程序的數據,並儘量快地把它扔到網絡上。
  • tcp是可靠的,而udp是不可靠的,upd不保證數據不丟失,也不保證package順序,可靠性只能經過上層應用把控
  • tcp由於是面向鏈接的,因此只能點對點傳輸,而upd由於不創建連接不須要維護狀態,能夠廣播
  • udp信息包的標題很短,只有8個字節,相對於TCP的20個字節信息包的額外開銷很小。

可見udp更適合對實時性要求高的廣播而tcp適合可靠傳輸

應用層

是OSI參考模型的最高層,它是計算機用戶,以及各類應用程序和網絡之間的接口,其功能是直接向用戶提供服務,完成用戶但願在網絡上完成的各類工做。

常見協議HTTP,FTP,SNMP等

TCP協議

SEQ

tcp包在發送時會爲每個包編號,稱爲sequence number(SEQ),以便接收的一方按照順序還原。萬一發生丟包,也能夠知道丟失的是哪個包。
包的下一個seq即next seq=seq+payload 好比當前seq=1,payload長度爲1400,那下一個seq就應該是1401.

ack

ack是acknowledgement的縮寫,表明確認的意思.須要注意的是ack=n 表明着確認seq<=n-1的包正常接收.

三次握手

TCP是面向鏈接的,不管哪一方向另外一方發送數據以前,都必須先在雙方之間創建一條鏈接。在TCP/IP協議中,TCP協議提供可靠的鏈接服務,鏈接是經過三次握手進行初始化的。三次握手的目的是同步鏈接雙方的序列號和確認號並交換 TCP窗口大小信息。

三次握手的圖示以下:

image-20190503222544384

wireshark抓包演示:

image-20190503214011085

  • 第一次client發起鏈接,發送一個SYN包表示創建鏈接,能夠看到此時seq=0,payload長度也是0
  • 第二次server對client應答,併發送鏈接請求. 發送一個包flags標誌位裏既包含syn又包含ack此時ack=x+1=0+1=1 ,seq=0
  • 第三次client接到server的應答後,對server的鏈接請求作應答,此時ack=y+1=0+1=1
爲何須要三次握手?

握手爲何是三次?不是兩次或者四次?

第一次握手是client發起鏈接請求,接到後server確認client能正常發送.

第二次握手是server對client的應答,接收到後client確認server能正常接收,且能正常發送

第三次握手是client對server的應答,接收到後server確認client能正常接收

至此,雙方就都能確保對方能夠正常接收和發送數據,tcp經過三次握手保證了鏈接的可靠性

四次揮手

tcp鏈接斷開的時候須要四次包發送操做,稱爲四次揮手:

image-20190503224512958

wireshark抓包示例:
image-20190503223327645

  • 第一次client送一個FIN包和一個seq612,以後client進入FIN_WAIT_1階段
  • server接收到以後回覆一個ack613,和seq945,表示收到了client的關閉請求,以後進入CLOSE_WAIT狀態,client進入FIN_WAIT_2狀態
  • 以後server處理完本身其餘的package以後發送一個FIN(實際用wireshark抓包沒看到FIN單獨出現的狀況,都是伴隨着一次ack)和seq945,此時server進入LAST_ACK狀態,再也不回覆消息.
  • client接收到server的FIN包後回覆一個ack946以後進入TIME_WAIT狀態,server接收到這個包以後直接進入CLOSED狀態,client等待了兩個msl(Maximum Segment Lifetime最大報文生存時間)以後沒有收到應答,表明server正常關閉,便也進入CLOSED狀態,關閉鏈接.
爲何要四次揮手?

爲何鏈接時候只須要三次握手,而斷開時須要四次?

由於鏈接的時候當server端收到client端的SYN鏈接請求報文後,能夠直接發送syn+ack報文,ack用來應答,syn用來請求鏈接. 可是在關閉的時候server收到client的fin請求不能當即回覆fin包,由於server可能還有其餘的包沒有接收或發送完畢. 因此server端只能先回一個ack,表示收到了client的關閉請求. 而後當server端處理好本身的包以後再發送一個fin報文來請求關閉鏈接.

滑動窗口

滑動窗口協議(Sliding Window Protocol),屬於TCP協議的一種應用,用於網絡數據傳輸時的流量控制,以免擁塞的發生。 該協議容許發送方在中止並等待確認前發送多個數據分組。 因爲發送方沒必要每發一個分組就停下來等待確認,所以該協議能夠加速數據的傳輸,提升網絡吞吐量。

在上面的例子中,咱們都是發送一個包,ack,再發另外一個包.能夠看出來,這樣的吞吐量並不大,發送端須要等接收端ack一個包以後才能發下一個包.滑動窗口就是爲了提升發送效率(一次發送一組package),並控制流量.

發送端的緩存結構以下圖所示,下圖的緩存分爲已發送已ack 已發送未ack 待發送 未發送四塊,其中已發送未ack和待發送稱爲發送窗口.
而接收端緩存(這裏沒有畫)分爲已接收 未接收準備接收 未接收不許備接收三塊,其中未接收準備接收稱爲接收窗口

滑動窗口的圖懶得畫了,直接偷的別人的圖: https://juejin.im/post/5c9f1d...

image-20190504135716557

image-20190504135751244

能夠看到已發送的package獲得了ack確認窗口左端纔會向右移一位.

TCP是雙工的協議,會話的雙方均可以同時接收、發送數據。TCP會話的雙方都各自維護一個「發送窗口」和一個「接收窗口」。其中各自的「接收窗口」大小取決於應用、系統、硬件的限制(TCP傳輸速率不能大於應用的數據處理速率)。各自的「發送窗口」則要和對方的「接收窗口」大小相同

tcp在三次創建鏈接時就會交換雙方的接收窗口大小,藉此來肯定發送窗口大小.

在收發過程當中能夠隨時調整窗口的大小來達到流量控制的目的.

image-20190504144450307

TCP重傳

tcp要保證數據可靠性,因此要有丟失重傳機制.

tcp的ack機制只會確認連續的最後一個包,好比A發送了1,2,3三個連續的包,B接收到以後會ack4,A拿到這個ack以後就知道B確認接收到了seq=4以前的全部包.

如今假如B沒接收到3號包,這時4號包來了,要怎麼應答呢? 此時不能應答4號包,不然A就覺得B收到了3

超時重傳

一種解決方案是B接收不到3,即便接收到了4也不ack,就在那死等3.而A發現B應答timeout以後會重傳3或3及其以後的包.超時重傳的缺點是須要等timeout,浪費時間.

快速重傳

TCP引入了一種叫Fast Retransmit 的算法,不以時間驅動,而以數據驅動重傳

若是包有丟失,接收方就連續ack丟失的那個包,發送方連續三次接收到相同的ack,就重傳這個包.

好比上面的例子,B沒拿到3號包就會ack3,此時A發來4號包,B仍是ack3.A發來5號包,B繼續ack3.

此時A拿到三個ack3就知道3號包丟失,因而立刻重傳3號包.B就收到3號包以後直接ack6.表明5號包以前都接收成功.

相關文章
相關標籤/搜索