無論走到哪里嚎幸,都應該記住,過去都是假的寄猩,回憶是一條沒有盡頭的路嫉晶,一切以往的春天都不復存在,就連那最堅韌而又狂亂的愛情歸根結(jié)底也不過是一種轉(zhuǎn)瞬即逝的現(xiàn)實田篇。 ——馬爾克斯
?
本文已經(jīng)收錄至我的GitHub,歡迎大家踴躍star 和 issues替废。
https://github.com/midou-tech/articles
點關(guān)注,不迷路 ??????
?
逛論壇看到一個帖子泊柬,標題說自己在學習網(wǎng)絡模型椎镣,經(jīng)常有人提到TCP粘包問題,他笑了兽赁。這個帖子討論人數(shù)還挺多的状答。既然看到冷守,順便解釋下這個問題。 TCP問題也算是計算機網(wǎng)絡中比較重要的一個知識點惊科,面試當然是必不可少的拍摇、工作中也經(jīng)常遇到與之相關(guān)的問題。龍叔不光講網(wǎng)絡網(wǎng)面的知識點馆截,其他后端知識點也是會經(jīng)常給大家嘮叨一番的授翻。關(guān)注我,精彩內(nèi)容不錯過?? 微信搜索 龍躍十二 即可無憂訂閱孙咪。
網(wǎng)絡模型
計算機網(wǎng)絡分層模型主要有OSI七層模型堪唐,TCP/IP五層模型,也有一種四層模型翎蹈,四層模型會把網(wǎng)卡層和物理層統(tǒng)稱為網(wǎng)絡接口層淮菠。
OSI七層模型存在于教科書了,TCP/IP五層模型是日常運用最為廣泛的一種網(wǎng)絡架構(gòu)模型荤堪。在學習網(wǎng)絡知識時也要把握住重點去學合陵,七層模型了解即可。
由上面的分層可以看出澄阳,TCP是存在于運輸層的概念拥知。但是TCP有兩種含義的,一種指的是TCP協(xié)議碎赢,一種是TCP協(xié)議族的統(tǒng)稱低剔。具體來說,IP或ICMP肮塞、TCP或UDP襟齿、TELNET或FTP、以及HTTP等都屬于TCP/IP的協(xié)議枕赵。
TCP層是干嘛的猜欺?
TCP是屬于傳輸層的協(xié)議,我說的TCP層指的是傳輸層拷窜,這點要統(tǒng)一开皿。
傳輸層最主要的功能就是能夠讓應用程序之間實現(xiàn)通信。一句話就說清楚了TCP層是干嘛的篮昧。
TCP層的數(shù)據(jù)是如何存在的赋荆?
TCP的定義,TCP是面向連接的恋谭、可靠的流式傳輸協(xié)議糠睡。概念往往是高度濃縮的經(jīng)典貨挽鞠,就比如這句疚颊,涵蓋了TCP傳輸建立方式狈孔,傳輸方式,特點材义。面向連接指的是兩個應用程序的傳輸是需要提前建立一個鏈接均抽,這個鏈接就是我們的VIP通道,保證兩個應用程序之間的通行是點對點的傳輸其掂。建立鏈接的過程就是面試秤突樱考的三次握手過程。
三次握手和四次揮手都會在后續(xù)文章重點剖析出來款熬,想了解的記住關(guān)注我深寥,微信搜索 龍躍十二 即可無憂訂閱。
流式傳輸說的數(shù)據(jù)傳輸方式贤牛,TCP層數(shù)據(jù)交互是流式的惋鹅,什么是流式?流你可以理解為水流殉簸,水流是沒有邊界的闰集。
可靠指的是TCP傳輸數(shù)據(jù)的特點,可靠的意思就是你發(fā)送的數(shù)據(jù)一定最大程度保證讓對方應用程序接收到般卑。TCP為提供可靠性傳輸武鲁,實行“順序控制”或“重發(fā)控制”機制。此外還具備“流控制(流量控制)”蝠检、“擁塞控制”沐鼠、提高網(wǎng)絡利用率等眾多功能。具體如何通過這些機制保證消息的可靠性叹谁。后續(xù)也會出相應的文章迟杂,不用提醒 趕緊關(guān)注我。
從定義我們很清楚的知道TCP的數(shù)據(jù)是字節(jié)流的方式存在的本慕。TCP發(fā)送數(shù)據(jù)單位準確叫法是數(shù)據(jù)段排拷。應用程序和TCP的交互是一次一個數(shù)據(jù)段(大小不等),TCP把應用程序交下來的數(shù)據(jù)僅僅看成是一連串的無結(jié)構(gòu)的字節(jié)流锅尘。TCP并不知道所傳送的字節(jié)流的含義监氢。
TCP不保證接收方應用程序所收到的數(shù)據(jù)段和發(fā)送方應用程序所發(fā)出的數(shù)據(jù)段具有對應大小的關(guān)系(例如,發(fā)送方應用程序交給發(fā)送方的TCP共10個數(shù)據(jù)段藤违,但接收方的TCP可能只用了4個數(shù)據(jù)段就把收到的字節(jié)流交付上層的應用程序)浪腐。接收方應用程序收到的字節(jié)流必須和發(fā)送方應用程序發(fā)出的字節(jié)流完全一樣。
包的概念是在那一層談到的顿乒?
數(shù)據(jù)幀(Frame):是一種信息單位议街,它的起始點和目的點都是數(shù)據(jù)鏈路層。
數(shù)據(jù)包(Packet):也是一種信息單位璧榄,它的起始和目的地是網(wǎng)絡層特漩。
數(shù)據(jù)報(Datagram):通常是指起始點和目的地都使用無連接網(wǎng)絡服務的的網(wǎng)絡層的信息單元吧雹。
段(Segment):通常是指起始點和目的地都是傳輸層的信息單元。
消息(message):是指起始點和目的地都在網(wǎng)絡層以上(經(jīng)常在應用層)的信息單元涂身。
元素(cell)是一種固定長度的信息雄卷,它的起始點和目的地都是數(shù)據(jù)鏈路層。
元素通常用于異步傳輸模式(ATM)和交換多兆位數(shù)據(jù)服務(SMDS)網(wǎng)絡等交換環(huán)境蛤售。
數(shù)據(jù)單元(data unit)指許多信息單元丁鹉。常用的數(shù)據(jù)單元有服務數(shù)據(jù)單元(SDU)、協(xié)議數(shù)據(jù)單元(PDU)悴能。
SDU是在同一機器上的兩層之間傳送信息揣钦。PDU是發(fā)送機器上每層的信息發(fā)送到接收機器上的相應層(同等層間交流用的)。
Packet(數(shù)據(jù)包):封裝的基本單元漠酿,它穿越網(wǎng)絡層和數(shù)據(jù)鏈路層的分解面拂盯。通常一個Packet映射成一個Frame,但也有例外:即當數(shù)據(jù)鏈路層執(zhí)行拆分或?qū)讉€Packet合成一個Frame的時候记靡。
數(shù)據(jù)鏈路層的PDU叫做Frame(幀)谈竿, 網(wǎng)絡層的PDU叫做Packet(數(shù)據(jù)包), TCP的叫做Segment(數(shù)據(jù)段)摸吠, UDP的叫做Datagram空凸。
一個Datagram可能被封裝成一個或幾個Packets,在數(shù)據(jù)鏈路層中傳輸幀和數(shù)據(jù)包都是數(shù)據(jù)的傳輸形式寸痢。幀呀洲,工作在二層,數(shù)據(jù)鏈路層傳輸?shù)氖菙?shù)據(jù)幀啼止,包含數(shù)據(jù)包道逗,并且增加相應MAC地址與二層信息;數(shù)據(jù)包献烦,工作在三層滓窍,網(wǎng)絡層傳輸?shù)氖菙?shù)據(jù)包,包含數(shù)據(jù)報文巩那,并且增加傳輸使用的IP地址等三層信息吏夯。
為什么面試官和大家還是會談論TCP粘包問題呢?
從上面很容易的出即横,第一噪生、TCP層傳輸是流式傳輸,不會發(fā)送數(shù)據(jù)包东囚。第二跺嗽、數(shù)據(jù)包是存在于網(wǎng)絡層的概念。那為啥還說TCP粘包問題呢?
自頂而下學習網(wǎng)絡的同學都知道應用程序首先要將自己的數(shù)據(jù)通過套接字發(fā)送桨嫁。應用層交付給TCP的是結(jié)構(gòu)化的數(shù)據(jù)植兰,結(jié)構(gòu)化的數(shù)據(jù)到了TCP層做流式傳輸。
流瞧甩,最大的問題是沒有邊界钉跷,沒有邊界就會造成數(shù)據(jù)粘在一起弥鹦,這種粘在一起就叫做粘包肚逸。當然有同學就要問了,那咋不叫粘段呢彬坏?這個朦促。。栓始。
具體描述下什么叫粘包务冕。
TCP粘包是指發(fā)送方發(fā)送的若干包數(shù)據(jù)到接收方接收時粘成一包,從接收緩沖區(qū)看幻赚,后一包數(shù)據(jù)的頭緊接著前一包數(shù)據(jù)的尾禀忆。
粘包發(fā)生在那些情況下?
TCP是端到端傳輸?shù)穆淠眨瑫rTCP連接是可復用的箩退。什么叫復用呢?復用就是一條連接可以供一臺主機上的多個進程使用佳谦。
1.由TCP連接復用造成的粘包問題戴涝。
如果沒有復用一個連接只提供給端到端的兩個進程使用,這是數(shù)據(jù)的傳輸方和發(fā)送方都是約定好了數(shù)據(jù)的格式的钻蔑,但是多個進程使用一個TCP連接啥刻,此時多種不同結(jié)構(gòu)的數(shù)據(jù)進到TCP的流式傳輸,邊界分割肯定會出這樣或者那樣的問題咪笑。
如果利用tcp每次發(fā)送數(shù)據(jù)可帽,就與對方建立連接,然后雙方發(fā)送完一段數(shù)據(jù)后窗怒,就關(guān)閉連接蘑拯,這樣就不會出現(xiàn)粘包問題
連接復用的問題,之后會出一系列TCP文章講解兜粘。所以趕緊關(guān)注我??申窘,防止走丟喔,微信搜索 龍躍十二孔轴,即可無憂訂閱剃法。
2.因為TCP默認會使用Nagle算法,此算法會導致粘包問題路鹰。
而Nagle算法主要做兩件事贷洲,1)只有上一個分組得到確認收厨,才會發(fā)送下一個分組;2)收集多個小分組优构,在一個確認到來時一起發(fā)送诵叁。
多個分組拼裝為一個數(shù)據(jù)段發(fā)送出去,如果沒有好的邊界處理钦椭,在解包的時候會發(fā)生粘包問題拧额。
3.數(shù)據(jù)包過大造成的粘包問題。
比如應用進程緩沖區(qū)的一條消息的字節(jié)的大小超過了發(fā)送緩沖區(qū)的大小彪腔,就有可能產(chǎn)生粘包問題侥锦。因為消息已經(jīng)被分割了,有可能一部分已經(jīng)被發(fā)送出去了德挣,對方已經(jīng)接受了恭垦,但是另外一部分可能剛放入套接口發(fā)送緩沖區(qū)里準備進一步發(fā)送,就直接導致接受的后一部分格嗅,直接導致了粘包問題的出現(xiàn)番挺。
4.流量控制,擁塞控制也可能導致粘包屯掖。
5.接收方不及時接收緩沖區(qū)的包玄柏,造成多個包接收。
大多數(shù)人都是知道Nagle算法懂扼、接收方不及時處理兩種情況造成的粘包問題禁荸,但是龍叔必須提醒你,其他幾種情況也是非常常見的阀湿,面試官也是超愛問赶熟,如果你能把其他三種也答出來,面試通過概率大很多陷嘴。
粘包問題如何處理映砖?
1.Nagle算法問題導致的,需要結(jié)合應用場景適當關(guān)閉該算法灾挨。
2.其他幾種情況的處理方法主要分兩種:
尾部標記序列邑退。通過特殊標識符表示數(shù)據(jù)包的邊界,例如\n\r劳澄,\t地技,或者一些隱藏字符。
頭部標記分步接收秒拔。在TCP報文的頭部加上表示數(shù)據(jù)長度莫矗。
應用層發(fā)送數(shù)據(jù)時定長發(fā)送。
本文涉及到很多計算機網(wǎng)絡的重點知識并沒有說清楚,但本文意在讓大家明白TCP粘包問題作谚,其他問題龍叔后期會陸續(xù)更新三娩。關(guān)注我,精彩內(nèi)容不錯過妹懒。