TCP粘包問題,真的那麼難懂麼,爲何我屢屢受挫??

無論走到哪裏,都應該記住,過去都是假的,回憶是一條沒有盡頭的路,一切以往的春天都不復存在,就連那最堅韌而又狂亂的愛情歸根結底也不過是一種轉瞬即逝的現實。 ——馬爾克斯

本文已經收錄至我的GitHub,歡迎大家踊躍star 和 issues。

https://github.com/midou-tech/articles

點關注,不迷路 ❤️❤️❤️

逛論壇看到一個帖子,標題說自己在學習網絡模型,經常有人提到TCP粘包問題,他笑了。這個帖子討論人數還挺多的。既然看到,順便解釋下這個問題。 TCP問題也算是計算機網絡中比較重要的一個知識點,面試當然是必不可少的、工作中也經常遇到與之相關的問題。龍叔不光講網絡網面的知識點,其他後端知識點也是會經常給大家嘮叨一番的。關注我,精彩內容不錯過💕 微信搜索 龍躍十二 即可無憂訂閱。

網絡模型

網絡模型

計算機網絡分層模型主要有OSI七層模型,TCP/IP五層模型,也有一種四層模型,四層模型會把網卡層和物理層統稱爲網絡接口層。

OSI七層模型存在於教科書了,TCP/IP五層模型是日常運用最爲廣泛的一種網絡架構模型。在學習網絡知識時也要把握住重點去學,七層模型瞭解即可。

由上面的分層可以看出,TCP是存在於運輸層的概念。但是TCP有兩種含義的,一種指的是TCP協議,一種是TCP協議族的統稱。具體來說,IP或ICMP、TCP或UDP、TELNET或FTP、以及HTTP等都屬於TCP/IP的協議。

TCP層是幹嘛的?

TCP是屬於傳輸層的協議,我說的TCP層指的是傳輸層,這點要統一。

**傳輸層最主要的功能就是能夠讓應用程序之間實現通信。**一句話就說清楚了TCP層是幹嘛的。

TCP層的數據是如何存在的?

TCP的定義,TCP是面向連接的、可靠的流式傳輸協議。概念往往是高度濃縮的經典貨,就比如這句,涵蓋了TCP傳輸建立方式,傳輸方式,特點。面向連接指的是兩個應用程序的傳輸是需要提前建立一個鏈接,這個鏈接就是我們的VIP通道,保證兩個應用程序之間的通行是點對點的傳輸。建立鏈接的過程就是面試常考的三次握手過程。

三次握手四次揮手都會在後續文章重點剖析出來,想了解的記住關注我,微信搜索 龍躍十二 即可無憂訂閱。

流式傳輸說的數據傳輸方式,TCP層數據交互是流式的,什麼是流式?流你可以理解爲水流,水流是沒有邊界的。

可靠指的是TCP傳輸數據的特點,可靠的意思就是你發送的數據一定最大程度保證讓對方應用程序接收到。TCP爲提供可靠性傳輸,實行“順序控制”或“重發控制”機制。此外還具備“流控制(流量控制)”、“擁塞控制”、提高網絡利用率等衆多功能。具體如何通過這些機制保證消息的可靠性。後續也會出相應的文章,不用提醒 趕緊關注我。

從定義我們很清楚的知道TCP的數據是字節流的方式存在的。TCP發送數據單位準確叫法是數據段。應用程序和TCP的交互是一次一個數據段(大小不等),TCP把應用程序交下來的數據僅僅看成是一連串的無結構字節流。TCP並不知道所傳送的字節流的含義。

TCP不保證接收方應用程序所收到的數據段和發送方應用程序所發出的數據段具有對應大小的關係(例如,發送方應用程序交給發送方的TCP共10個數據段,但接收方的TCP可能只用了4個數據段就把收到的字節流交付上層的應用程序)。接收方應用程序收到的字節流必須和發送方應用程序發出的字節流完全一樣。

包的概念是在那一層談到的?

  • 數據幀(Frame):是一種信息單位,它的起始點和目的點都是數據鏈路層。

  • 數據包(Packet):也是一種信息單位,它的起始和目的地是網絡層。

  • 數據報(Datagram):通常是指起始點和目的地都使用無連接網絡服務的的網絡層的信息單元。

  • 段(Segment):通常是指起始點和目的地都是傳輸層的信息單元。

  • 消息(message):是指起始點和目的地都在網絡層以上(經常在應用層)的信息單元。

  • 元素(cell)是一種固定長度的信息,它的起始點和目的地都是數據鏈路層。

元素通常用於異步傳輸模式(ATM)和交換多兆位數據服務(SMDS)網絡等交換環境。

數據單元(data unit)指許多信息單元。常用的數據單元有服務數據單元(SDU)、協議數據單元(PDU)。

SDU是在同一機器上的兩層之間傳送信息。PDU是發送機器上每層的信息發送到接收機器上的相應層(同等層間交流用的)。

Packet(數據包):封裝的基本單元,它穿越網絡層和數據鏈路層的分解面。通常一個Packet映射成一個Frame,但也有例外:即當數據鏈路層執行拆分或將幾個Packet合成一個Frame的時候。

數據鏈路層的PDU叫做Frame(幀),
網絡層的PDU叫做Packet(數據包),
TCP的叫做Segment(數據段), UDP的叫做Datagram。

一個Datagram可能被封裝成一個或幾個Packets,在數據鏈路層中傳輸幀和數據包都是數據的傳輸形式。幀,工作在二層,數據鏈路層傳輸的是數據幀,包含數據包,並且增加相應MAC地址與二層信息;數據包,工作在三層,網絡層傳輸的是數據包,包含數據報文,並且增加傳輸使用的IP地址等三層信息。

爲什麼面試官和大家還是會談論TCP粘包問題呢?

從上面很容易的出,第一、TCP層傳輸是流式傳輸,不會發送數據包。第二、數據包是存在於網絡層的概念。那爲啥還說TCP粘包問題呢?

自頂而下學習網絡的同學都知道應用程序首先要將自己的數據通過套接字發送。應用層交付給TCP的是結構化的數據,結構化的數據到了TCP層做流式傳輸。

,最大的問題是沒有邊界,沒有邊界就會造成數據粘在一起,這種粘在一起就叫做粘包。當然有同學就要問了,那咋不叫粘段呢?這個。。。

具體描述下什麼叫粘包。

TCP粘包是指發送方發送的若干包數據到接收方接收時粘成一包,從接收緩衝區看,後一包數據的頭緊接着前一包數據的尾。

粘包發生在那些情況下?

TCP是端到端傳輸的,同時TCP連接是可複用的。什麼叫複用呢?複用就是一條連接可以供一臺主機上的多個進程使用。

**1.**由TCP連接複用造成的粘包問題。

如果沒有複用一個連接只提供給端到端的兩個進程使用,這是數據的傳輸方和發送方都是約定好了數據的格式的,但是多個進程使用一個TCP連接,此時多種不同結構的數據進到TCP的流式傳輸,邊界分割肯定會出這樣或者那樣的問題。

如果利用tcp每次發送數據,就與對方建立連接,然後雙方發送完一段數據後,就關閉連接,這樣就不會出現粘包問題

連接複用的問題,之後會出一系列TCP文章講解。所以趕緊關注我😆,防止走丟喔,微信搜索 龍躍十二,即可無憂訂閱。

**2.**因爲TCP默認會使用Nagle算法,此算法會導致粘包問題。

而Nagle算法主要做兩件事,1)只有上一個分組得到確認,纔會發送下一個分組;2)收集多個小分組,在一個確認到來時一起發送。

多個分組拼裝爲一個數據段發送出去,如果沒有好的邊界處理,在解包的時候會發生粘包問題。

**3.**數據包過大造成的粘包問題。

比如應用進程緩衝區的一條消息的字節的大小超過了發送緩衝區的大小,就有可能產生粘包問題。因爲消息已經被分割了,有可能一部分已經被髮送出去了,對方已經接受了,但是另外一部分可能剛放入套接口發送緩衝區裏準備進一步發送,就直接導致接受的後一部分,直接導致了粘包問題的出現。

**4.**流量控制,擁塞控制也可能導致粘包。

**5.**接收方不及時接收緩衝區的包,造成多個包接收。

大多數人都是知道Nagle算法接收方不及時處理兩種情況造成的粘包問題,但是龍叔必須提醒你,其他幾種情況也是非常常見的,面試官也是超愛問,如果你能把其他三種也答出來,面試通過概率大很多。

粘包問題如何處理?

1.Nagle算法問題導致的,需要結合應用場景適當關閉該算法。

2.其他幾種情況的處理方法主要分兩種:

  • 尾部標記序列。通過特殊標識符表示數據包的邊界,例如\n\r,\t,或者一些隱藏字符。

  • 頭部標記分步接收。在TCP報文的頭部加上表示數據長度。

  • 應用層發送數據時定長髮送。

本文涉及到很多計算機網絡的重點知識並沒有說清楚,但本文意在讓大家明白TCP粘包問題,其他問題龍叔後期會陸續更新。關注我,精彩內容不錯過。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章