不管走到哪裏,都應該記住,過去都是假的,回憶是一條沒有盡頭的路,一切以往的春天都不復存在,就連那最堅韌而又狂亂的愛情歸根結底也不過是一種轉瞬即逝的現實。 ——馬爾克斯git
本文已經收錄至個人GitHub,歡迎你們踊躍star 和 issues。github
逛論壇看到一個帖子,標題說本身在學習網絡模型,常常有人提到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傳輸創建方式,傳輸方式,特色。面向鏈接指的是兩個應用程序的傳輸是須要提早創建一個連接,這個連接就是咱們的VIP通道,保證兩個應用程序之間的通行是點對點的傳輸。創建連接的過程就是面試常考的三次握手過程。異步
三次握手和四次揮手都會在後續文章重點剖析出來,想了解的記住關注我,微信搜索 龍躍十二 便可無憂訂閱。tcp
流式傳輸說的數據傳輸方式,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地址等三層信息。
從上面很容易的出,第1、TCP層傳輸是流式傳輸,不會發送數據包。第2、數據包是存在於網絡層的概念。那爲啥還說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粘包問題,其餘問題龍叔後期會陸續更新。關注我,精彩內容不錯過。