每次面試都被問TCP粘包問題,今天終於可以說的清清楚楚了
無論走到哪裡,都應該記住,過去都是假的,回憶是一條沒有盡頭的路,一切以往的春天都不復存在,就連那最堅韌而又狂亂的愛情歸根結底也不過是一種轉瞬即逝的現實。 ——馬爾克斯
本文已經收錄至我的GitHub,歡迎大家踴躍star 和 issues。
點關注,不迷路 ❤️❤️❤️
逛論壇看到一個帖子,標題說自己在學習網路模型,經常有人提到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每次傳送資料,就與對方建立連線,然後雙方傳送完一段資料後,就關閉連線,這樣就不會出現粘包問題
2. 因為TCP預設會使用Nagle演算法,此演算法會導致粘包問題。
而Nagle演算法主要做兩件事,1)只有上一個分組得到確認,才會傳送下一個分組;2)收集多個小分組,在一個確認到來時一起傳送。
多個分組拼裝為一個資料段傳送出去,如果沒有好的邊界處理,在解包的時候會發生粘包問題。
3. 資料包過大造成的粘包問題。
比如應用程式緩衝區的一條訊息的位元組的大小超過了傳送緩衝區的大小,就有可能產生粘包問題。因為訊息已經被分割了,有可能一部分已經被髮送出去了,對方已經接受了,但是另外一部分可能剛放入套介面傳送緩衝區裡準備進一步傳送,就直接導致接受的後一部分,直接導致了粘包問題的出現。
4. 流量控制,擁塞控制也可能導致粘包。
5. 接收方不及時接收緩衝區的包,造成多個包接收。
大多數人都是知道Nagle演算法、接收方不及時處理兩種情況造成的粘包問題,但是龍叔必須提醒你,其他幾種情況也是非常常見的,面試官也是超愛問,如果你能把其他三種也答出來,面試透過機率大很多。
粘包問題如何處理?
1.Nagle演算法問題導致的,需要結合應用場景適當關閉該演算法。
2.其他幾種情況的處理方法主要分兩種:
-
尾部標記序列。透過特殊識別符號表示資料包的邊界,例如nr,t,或者一些隱藏字元。
-
頭部標記分步接收。在TCP報文的頭部加上表示資料長度。
-
應用層傳送資料時定長髮送。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4662/viewspace-2825186/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TCP粘包拆包問題TCP
- Go TCP 粘包問題GoTCP
- TCP協議粘包問題詳解TCP協議
- TCP 粘包 - 拆包問題及解決方案TCP
- 大家面試時都被問到了哪些問題面試
- 粘包問題
- 詳說tcp粘包和半包TCP
- 粘包/拆包問題一直都存在,只是到TCP就拆不動了。TCP
- Netty中使用MessagePack時的TCP粘包問題與解決方案NettyTCP
- Socket 粘包和分包問題
- 深入學習Netty(5)——Netty是如何解決TCP粘包/拆包問題的?NettyTCP
- 粘包問題原因和解決方法
- 25. Socket與粘包問題
- socket的半包,粘包與分包的問題
- TCP 粘包拆包TCP
- 結合RPC框架通訊談 netty如何解決TCP粘包問題RPC框架NettyTCP
- netty 解決粘包 和 分包的問題Netty
- java nio解決半包 粘包問題Java
- Netty拾遺(七)——粘包與拆包問題Netty
- TCP的粘包拆包技術TCP
- JavaScript中揹包問題(面試題)JavaScript面試題
- Netty解決粘包和拆包問題的四種方案Netty
- 詢問面試官的面試問題面試
- 面試被問TopK問題,可以這樣優雅的解答面試TopK
- 粘包問題、socketserver模組實現併發Server
- Java面試必問面試題,你掌握了嗎?Java面試題
- 【面試】徹底理解 TCP 及面試常問面試TCP
- Go etcd 的依賴問題終於解決了。。。Go
- Netty2:粘包/拆包問題與使用LineBasedFrameDecoder的解決方案Netty
- 面試中關於Redis的問題看這篇就夠了面試Redis
- 面試反問問題面試
- 40個Java集合面試問題和答案,面試奇葩問題,你掌握了嗎?Java面試
- 訊息粘包 和 訊息不完整 問題
- 關於Integer面試的一個問題面試
- 終於搞定了vertical-align:baseline對齊的問題
- 昨天的面試問題面試
- go語言處理TCP拆包/粘包GoTCP
- 又被奪命連環問了!從一道關於定時任務的面試題說起。面試題