關(guān)于TCP收到數(shù)據(jù)粘包問(wèn)題——Nagle算法

  • 在一個(gè)項(xiàng)目中,要在TCP連接的客戶端和服務(wù)器之間發(fā)送json形式的數(shù)據(jù)。遇到了一個(gè)問(wèn)題,有時(shí)候數(shù)據(jù)發(fā)送端連續(xù)多次調(diào)用send()函數(shù)發(fā)送多條json字符串時(shí),接收端用recv()函數(shù)接收一條數(shù)據(jù)是一個(gè)組合多條json的大字符串,并不是期望的收到多條分割開(kāi)的json字符串。這就是TCP的粘包問(wèn)題。
  • 這就導(dǎo)致在使用cJSON_Parse()函數(shù)對(duì)json字符串進(jìn)行解析時(shí),只能解析出第一條完整的json,而后面的就丟棄了。這種情況對(duì)于每條json是一條命令來(lái)說(shuō),是很糟糕的。
  • 其實(shí)這種每條json是一個(gè)命令的業(yè)務(wù)需求,使用UDP來(lái)發(fā)送數(shù)據(jù),就不會(huì)發(fā)生粘包問(wèn)題。UDP是數(shù)據(jù)報(bào)傳輸協(xié)議,顧名思義其就是每次發(fā)送一個(gè)數(shù)據(jù)報(bào),不會(huì)進(jìn)行多條的封裝拼湊再集體發(fā)送。

在socket網(wǎng)絡(luò)程序中,TCP和UDP分別是面向連接和非面向連接的。因此TCP的socket編程,收發(fā)兩端(客戶端和服務(wù)器端)都要有成對(duì)的socket,因此,發(fā)送端為了將多個(gè)發(fā)往接收端的包,更有效的發(fā)到對(duì)方,使用了優(yōu)化方法(Nagle算法),將多次間隔較小、數(shù)據(jù)量小的數(shù)據(jù),合并成一個(gè)大的數(shù)據(jù)塊,然后進(jìn)行封包。這樣,接收端,就難于分辨出來(lái)了,必須自己提供科學(xué)的拆包機(jī)制。

對(duì)于UDP,不會(huì)使用塊的合并優(yōu)化算法,這樣,實(shí)際上目前認(rèn)為,是由于UDP支持的是一對(duì)多的模式,所以接收端的skbuff(套接字緩沖區(qū))采用了鏈?zhǔn)浇Y(jié)構(gòu)來(lái)記錄每一個(gè)到達(dá)的UDP包,在每個(gè)UDP包中就有了消息頭(消息來(lái)源地址,端口等信息),這樣,對(duì)于接收端來(lái)說(shuō),就容易進(jìn)行區(qū)分處理了。所以UDP不會(huì)出現(xiàn)粘包問(wèn)題。
https://www.cnblogs.com/kex1n/p/6502002.html
TCP通信粘包問(wèn)題分析和解決(全)
====================================================================

TCP的Nagle算法和延遲ACK

  • Nagle算法的操作過(guò)程請(qǐng)參看Wiki,它減少了大量小包的發(fā)送,實(shí)際上就是基于小包的停-等協(xié)議。在等待已經(jīng)發(fā)出的包被確認(rèn)之前,發(fā)送端利用這段時(shí)間可以積累應(yīng)用下來(lái)的數(shù)據(jù),使其大小趨向于增加。這是避免糊涂窗口綜合癥的一種有效方法,請(qǐng)注意,糊涂窗口指的是接收端的糊涂,而不是發(fā)送端的糊涂,接收端不管三七二十一得通告自己的接收窗口大小,絲毫不管這會(huì)在發(fā)送端產(chǎn)生大量小包。然而發(fā)送端可以不糊涂,你通告你的,我就是不發(fā),你糊涂我不糊涂,你不斷通告很小的數(shù)值,我不予理睬,我有自己的方法,直到收到已經(jīng)發(fā)出包的ACK才會(huì)繼續(xù)發(fā)送,這就是Nagle算法的糊涂抵制方案。
  • 治療糊涂窗口綜合癥有兩種方式,一種是“你糊涂我不糊涂”的方式,即上述的Nagle算法的方式,另外一種是“治療接收端的糊涂”的方式,其中一種機(jī)制是延遲ACK(還有其它機(jī)制,比如不發(fā)送小窗口通告等)。可以看出,這兩種方式中都在試圖減少包的發(fā)送量,二者殊途同歸的解決了同一問(wèn)題,對(duì)于發(fā)送方而言,不理會(huì)接收端的小窗口通告等于說(shuō)不馬上發(fā)送小包,小包得以有時(shí)間積累成大包,對(duì)于接收方而言,延遲ACK可以拖延ACK發(fā)送時(shí)間,進(jìn)而延遲窗口通告,在這段時(shí)間內(nèi),接收窗口有機(jī)會(huì)進(jìn)一步(由于應(yīng)用程序處理)放大。單獨(dú)理解這兩種方式都是簡(jiǎn)單的,但是一旦它們混在一起使用,情況就會(huì)非常不幸!因?yàn)?..
  • Nagle算法和延遲ACK作用在方向相反的數(shù)據(jù)包和針對(duì)該數(shù)據(jù)包的確認(rèn)包上,因此它們的作用力會(huì)相悖,結(jié)果就是誰(shuí)也不能發(fā)包。就像一根繩子上拴兩只青蛙一樣,被對(duì)方牽制誰(shuí)也跑不了!關(guān)鍵點(diǎn)在于,小包的發(fā)送依賴于ACK,然而延遲ACK阻止了ACK的即時(shí)發(fā)送,形成了僵持狀態(tài)。本來(lái)只是為了減少網(wǎng)絡(luò)上小包的數(shù)量(再次強(qiáng)調(diào)Nagle算法以及延遲ACK的目的,注意,糊涂窗口綜合癥只是網(wǎng)絡(luò)上小包泛濫的原因之一!),卻人為引入了大量的延遲!
  • 此處有一個(gè)通用的解釋,Nagle算法的小包發(fā)送依賴于接收端對(duì)小包得快速確認(rèn),因此接收端對(duì)待ACK而言,應(yīng)該朝著延遲ACK相反俄方向用力,即快速ACK;相對(duì)的,如果在接收端啟用了延遲ACK,發(fā)送端就應(yīng)該不斷發(fā)送數(shù)據(jù)包,不管是大包還是小包(不考慮稍帶ACK的影響),因?yàn)榘l(fā)送端已經(jīng)不能指望接收端正常ACK數(shù)據(jù)包了,即發(fā)送端應(yīng)該禁掉Nagle算法。以上解釋背后的思想就是數(shù)據(jù)包和ACK包是相關(guān)的,力應(yīng)該往一個(gè)方向使,一邊拉另一邊就要推,如果兩邊都拉,力就會(huì)抵消掉,陷入僵持。不幸點(diǎn)或者說(shuō)悲哀的地方在于,Nagle算法和延遲ACK機(jī)制都是“拉方案”!劃船的人都知道,劃槳手有兩種座位布局,要么超同一個(gè)方向,要么面朝不同的方向,后者和TCP數(shù)據(jù)包和ACK很類似,要想船往前走,必須朝一個(gè)方向劃,雖然他們面朝相反的方向。

https://blog.csdn.net/dog250/article/details/21303679
再次談?wù)凾CP的Nagle算法與TCP_CORK選項(xiàng)

https://blog.csdn.net/wdscq1234/article/details/52432095
TCP-IP詳解:Nagle算法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.這篇文章不是本人原創(chuàng)的,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,340評(píng)論 6 174
  • 個(gè)人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,185評(píng)論 0 8
  • TCP/IP詳解系列,關(guān)于tcp擁塞控制和數(shù)據(jù)流的地方講的不細(xì)致,或許是涉及概念/算法太多,作者略去了一些對(duì)初學(xué)者...
    半島夏天閱讀 1,207評(píng)論 0 1
  • 套接字選項(xiàng)SO_RESUEADDR 即使端口處于2MSL狀態(tài),使用該選項(xiàng),仍然能夠在該端口建立連接。服務(wù)器常會(huì)設(shè)置...
    Myth52125閱讀 1,518評(píng)論 0 0
  • 轉(zhuǎn)自原文:TCP、UDP以及TCP滑窗,它們的區(qū)別注:文中提到TCP傳輸過(guò)程的特點(diǎn),以及“粘包”的原因和解決方案,...
    半島夏天閱讀 3,679評(píng)論 2 31

友情鏈接更多精彩內(nèi)容