TCP 的斷包和粘包


以太網中存在一個對於幀的有效數據大小的限制,即 MTU,以太網的 MTU 為 1500 字節。

一、斷包

image.png

就是說發送端一次發送的消息長度過大,如果超過了 MTU,那么 ip 會對其進行分片。

在網絡編程中,要避免出現 IP 分片。因為是 IP 層是沒有超時重傳機制的,如果 IP 層對一個數據包進行了分片,只要有一個分片丟失了,只能依賴於傳輸層進行重傳,結果是所有的分片都要重傳一遍,這個代價有點大。由此可見,IP 分片會大大降低傳輸層傳送數據的成功率,所以要避免 IP 分片。

對於 UDP 包,我們需要在應用層去限制每個包的大小,一般不要超過 1472 字節,即以太網 MTU(1500)- UDP 首部(8)- IP 首部(20)。

對於 TCP 數據,應用層就不需要考慮這個問題了,因為傳輸層已經做了。在建立連接的三次握手的過程中,連接雙方會相互通告MSS(Maximum Segment Size,最大報文段長度),一般 MSS = MTU - IP 首部(20)- TCP 首部(20),每次發送的 TCP 數據都不會超過雙方 MSS 的最小值,所以就保證了 IP 數據報不會超過 MTU,避免了 IP 分片。

而斷包就是因為 MSS 的存在,當消息長度過大,例如超過了 1460 字節(因為 tcp 首部一般為 20 個字節,ip 首部為 20 個字節),那么 tcp 就會將其分片,然后每片被 tcp 封裝,然后由 ip 封裝,最后被傳輸到接收端,這樣子當接收端接收到消息后,就會不清楚這是不是一個完整的消息。

二、粘包

為了提高網絡利用率,當傳輸層發現傳輸的數據長度太小時,會等待多個消息一起發送,這時候就會提高網絡利用率,但是當接收端接收過以后,會不知道這是一個完整的消息,還是多個消息在一起。從而有可能將其作為一個消息來處理。nagle 算法就是實現的這個功能。

對於斷包和粘包的通常處理方法為將消息封裝為一定的格式,例如每個消息頭部為 aa,尾部為 55,或者將整個消息的有效長度標明,這樣子當接收端接收到消息之后,就可以以此來分辨消息是不是我完整的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM