日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计网 - TCP 的封包格式:TCP 为什么要粘包和拆包?

發布時間:2025/3/21 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计网 - TCP 的封包格式:TCP 为什么要粘包和拆包? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • Pre
  • TCP 的拆包和粘包
    • TCP數據發送
    • TCP Segment
    • Sequence Number 和 Acknowledgement Number
    • MSS(Maximun Segment Size)
  • Question : TCP 協議是如何恢復數據的順序的,TCP 拆包和粘包的作用是什么?


Pre

今天我們將從穩定性角度深挖 TCP 協議的運作機制

如今,大半個互聯網都建立在 TCP 協議之上,我們使用的 HTTP 協議、消息隊列、存儲、緩存,都需要用到 TCP 協議——這是因為 TCP 協議提供了可靠性

簡單來說,可靠性就是讓數據無損送達。但若是考慮到成本,就會變得非常復雜——因為還需要盡可能地提升吞吐量、降低延遲、減少丟包率。

TCP 協議具有很強的實用性,而可靠性又是 TCP 最核心的能力 。具體來說,從一個終端有序地發出多個數據包,經過一個復雜的網絡環境,到達目的地的時候會變得無序,而可靠性要求數據恢復到原始的順序。這里先提出兩個問題:

  • TCP 協議是如何恢復數據的順序的?

  • 拆包和粘包的作用是什么?

那么帶著這兩個問題開始今天的學習。


TCP 的拆包和粘包

TCP數據發送

TCP 是一個傳輸層協議

TCP 發送數據的時候,往往不會將數據一次性發送

而是將數據拆分成很多個部分,然后再逐個發送。像下圖這樣:

同樣的,在目的地,TCP 協議又需要逐個接收數據。

請 思考,TCP 為什么不一次發送完所有的數據?比如我們要傳一個大小為 10M 的文件,對于應用層而言,就是一次傳送完成的。而傳輸層的協議為什么不選擇將這個文件一次發送完呢?

這里有很多原因,

  • 比如為了穩定性,一次發送的數據越多,出錯的概率越大。
  • 再比如說為了效率,網絡中有時候存在著并行的路徑,拆分數據包就能更好地利用這些并行的路徑。
  • 再有,比如發送和接收數據的時候,都存在著緩沖區。如下圖所示:

緩沖區是在內存中開辟的一塊區域,目的是緩沖。因為大量的應用頻繁地通過網卡收發數據,這個時候,網卡只能一個一個處理應用的請求。當網卡忙不過來的時候,數據就需要排隊,也就是將數據放入緩沖區。如果每個應用都隨意發送很大的數據,可能導致其他應用實時性遭到破壞。

還有一些原因 比如內存的最小分配單位是頁表,如果數據的大小超過一個頁表,可能會存在頁面置換問題,造成性能的損失。

總之,方方面面的原因:在傳輸層封包不能太大

這種限制,往往是以緩沖區大小為單位的。也就是 TCP 協議,會將數據拆分成不超過緩沖區大小的一個個部分。每個部分有一個獨特的名詞,叫作 TCP 段(TCP Segment)

在接收數據的時候,一個個 TCP 段又被重組成原來的數據。

像這樣,數據經過拆分,然后傳輸,然后在目的地重組,俗稱拆包。所以拆包是將數據拆分成多個 TCP 段傳輸。

那么粘包是什么呢?有時候,如果發往一個目的地的多個數據太小了,為了防止多次發送占用資源,TCP 協議有可能將它們合并成一個 TCP 段發送,在目的地再還原成多個數據,這個過程俗稱粘包。所以粘包是將多個數據合并成一個 TCP 段發送


TCP Segment

那么一個 TCP 段長什么樣子呢?下圖是一個 TCP 段的格式:

我們可以看到,TCP 的很多配置選項和數據粘在了一起,作為一個 TCP 段。

顯然, 把每一部分都記住似乎不太現實,先把其中最主要的部分理解。

TCP 協議就是依靠每一個 TCP 段工作的,所以你每認識一個 TCP 的能力,幾乎都會找到在 TCP Segment 中與之對應的字段。 接下來 認識它們。

  • Source Port/Destination Port 描述的是發送端口號和目標端口號,代表發送數據的應用程序和接收數據的應用程序。比如 80 往往代表 HTTP 服務,22 往往是 SSH 服務……

  • Sequence Number 和 Achnowledgment Number 是保證可靠性的兩個關鍵

  • Data Offset 是一個偏移量。這個量存在的原因是 TCP Header 部分的長度是可變的,因此需要一個數值來描述數據從哪個字節開始。

  • Reserved 是很多協議設計會保留的一個區域,用于日后擴展能力。

  • URG/ACK/PSH/RST/SYN/FIN 是幾個標志位,用于描述 TCP 段的行為。也就是一個 TCP 封包到底是做什么用的

1)URG 代表這是一個緊急數據,比如遠程操作的時候,用戶按下了 Ctrl+C,要求終止程序,這種請求需要緊急處理。

2)ACK 代表響應, 所有的消息都必須有 ACK,這是 TCP 協議確保穩定性的一環。

3)PSH 代表數據推送,也就是在傳輸數據的意思。

4)SYN 同步請求,也就是申請握手。

5)FIN 終止請求,也就是揮手。

特別說明一下:以上這 5 個標志位,每個占了一個比特,可以混合使用。比如 ACK 和 SYN 同時為 1,代表同步請求和響應被合并了。這也是 TCP 協議,為什么是三次握手的原因之一

  • Window 也是 TCP 保證穩定性并進行流量控制的工具,后續會 TCP 的穩定性:滑動窗口和流速控制是中詳細介紹。

  • Checksum 是校驗和,用于校驗 TCP 段有沒有損壞。

  • Urgent Pointer 指向最后一個緊急數據的序號(Sequence Number)。它存在的原因是:有時候緊急數據是連續的很多個段,所以需要提前告訴接收方進行準備。

  • Options 中存儲了一些可選字段,比如接下來我們要討論的 MSS(Maximun Segment Size)。

  • Padding 存在的意義是因為 Options 的長度不固定,需要 Pading 進行對齊。


Sequence Number 和 Acknowledgement Number

在 TCP 協議的設計當中,數據被拆分成很多個部分,部分增加了協議頭。合并成為一個 TCP 段,進行傳輸。這個過程,我們俗稱拆包。這些 TCP 段經過復雜的網絡結構,由底層的 IP 協議,負責傳輸到目的地,然后再進行重組。

這里請你思考一個問題:穩定性要求數據無損地傳輸,也就是說拆包獲得數據,又需要恢復到原來的樣子。而在復雜的網絡環境當中,即便所有的段是順序發出的,也不能保證它們順序到達,因此,發出的每一個 TCP 段都需要有序號。這個序號,就是 Sequence Number(Seq)


如上圖所示。發送數據的時候,為每一個 TCP 段分配一個自增的 Sequence Number。接收數據的時候,雖然得到的是亂序的 TCP 段,但是可以通過 Seq 進行排序。

但是這樣又會產生一個新的問題——接收方如果要回復發送方,也需要這個 Seq。而網絡的兩個終端,去同步一個自增的序號是非常困難的。因為任何兩個網絡主體間,時間都不能做到完全同步,又沒有公共的存儲空間,無法共享數據,更別說實現一個分布式的自增序號了。

其實這個問題的本質就好像兩個人在說話一樣,我們要確保他們說出去的話,和回答之間的順序。因為 TCP 是一個雙工的協議,兩邊可能會同時說話。所以聰明的科學家想到了確定一句話的順序,需要兩個值去描述——也就是發送的字節數和接收的字節數

我們重新定義一下 Seq(如上圖所示),對于任何一個接收方,如果知道了發送者發送某個 TCP 段時,已經發送了多少字節的數據,那么就可以確定發送者發送數據的順序。

但是這里有一個問題。如果接收方也向發送者發送了數據請求(或者說雙方在對話),接收方就不知道發送者發送的數據到底對應哪一條自己發送的數據了。

舉個例子:下面 A 和 B 的對話中,我們可以確定他們彼此之間接收數據的順序。但是無法確定數據之間的關聯關系,所以只有 Sequence Number 是不夠的。

A:今天天氣好嗎?A:今天你開心嗎?B:開心B:天氣不好

人類很容易理解這幾句話的順序,但是對于機器來說就需要特別的標注。因此我們還需要另一個數據,就是每個 TCP 段發送時,發送方已經接收了多少數據。用 Acknowledgement Number 表示,下面簡寫為 ACK。

下圖中,終端發送了三條數據,并且接收到四條數據,通過觀察,根據接收到的數據中的 Seq 和 ACK,將發送和接收的數據進行排序。


例如上圖中,發送方發送了 100 字節的數據,而接收到的(Seq = 0 和 Seq =100)的兩個封包,都是針對發送方(Seq = 0)這個封包的。發送 100 個字節,所以接收到的 ACK 剛好是 100。說明(Seq= 0 和 Seq= 100)這兩個封包是針對接收到第 100 個字節數據后,發送回來的。這樣就確定了整體的順序

注意,無論 Seq 還是 ACK,都是針對“對方”而言的。是對方發送的數據和對方接收到的數據 。 我們在實際的工作當中,可以通過 Whireshark 調試工具觀察兩個 TCP 連接的 Seq和 ACK。


MSS(Maximun Segment Size)

接下來,我們討論下 MSS,它也是面試經常會問到的一個 TCP Header 中的可選項(Options),這個可選項控制了 TCP 段的大小,它是一個協商字段(Negotiate)。協議是雙方都要遵循的標準,因此配置往往不能由單方決定,需要雙方協商。

TCP 段的大小(MSS)涉及發送、接收緩沖區的大小設置,雙方實際發送接收封包的大小,對拆包和粘包的過程有指導作用,因此需要雙方去協商

如果這個字段設置得非常大,就會帶來一些影響。

  • 首先對方可能會拒絕,作為服務的提供方,你可能不會愿意接收太大的 TCP 段。因為大的 TCP 段,會降低性能,比如內存使用的性能。 還有就是資源的占用。一個用戶占用服務器太多的資源,意味著其他的用戶就需要等待或者降低他們的服務質量

  • 其次,支持 TCP 協議工作的 IP 協議,工作效率會下降

TCP 協議不肯拆包,IP 協議就需要拆出大量的包。那么 IP 協議為什么需要拆包呢?這是因為在網絡中,每次能夠傳輸的數據不可能太大,這受限于具體的網絡傳輸設備,也就是物理特性。但是 IP 協議,拆分太多的封包并沒有意義。因為可能會導致屬于同個 TCP 段的封包被不同的網絡路線傳輸,這會加大延遲。同時,拆包,還需要消耗硬件和計算資源。

那是不是 MSS 越小越好呢?MSS 太小的情況下,會浪費傳輸資源(降低吞吐量)。因為數據被拆分之后,每一份數據都要增加一個頭部。如果 MSS 太小,那頭部的數據占比會上升,這讓吞吐量成為一個災難。所以在使用的過程當中,MSS 的配置,往往都是一個折中的方案

不要去猜想什么樣的方案是最合理的,而是要嘗試去用實驗證明它,一切都要用實驗依據說話。


Question : TCP 協議是如何恢復數據的順序的,TCP 拆包和粘包的作用是什么?

Answer:

TCP 拆包的作用是將任務拆分處理,降低整體任務出錯的概率,以及減小底層網絡處理的壓力。拆包過程需要保證數據經過網絡的傳輸,又能恢復到原始的順序。這中間,需要數學提供保證順序的理論依據。 TCP 利用(發送字節數、接收字節數)的唯一性來確定封包之間的順序關系

粘包是為了防止數據量過小,導致大量的傳輸,而將多個 TCP 段合并成一個發送。

總結

以上是生活随笔為你收集整理的计网 - TCP 的封包格式:TCP 为什么要粘包和拆包?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。