粘包現(xiàn)象展示
一上來就枯燥的文字,難免容易犯困,所以我先演示一下粘包現(xiàn)象:
我們的預期是,服務端打印出hello,I am Toranto這兩個字符串,兩個字符串經(jīng)編碼之后的字節(jié)總長度為17個字節(jié),但是我們看結(jié)果:
ps:b''是表示字節(jié)的意思,和我們之前用的f''(format)格式化用法是一樣的,單、雙、三引號一樣。可以了解一下:
好了回歸粘包現(xiàn)象,我們看到上圖,我們采用兩次接收數(shù)據(jù)的方式,兩次都接收20個字節(jié),但是發(fā)送端發(fā)送的兩次總字節(jié)只有17個字節(jié)長度,所以,tcp基于流式的協(xié)議,會先發(fā)送第一段字節(jié)到一個緩沖區(qū),如果時間間隔很短,則tcp會等第二段字也發(fā)送到這個緩沖區(qū)再統(tǒng)一發(fā)送到接收端這邊,兩次內(nèi)容的粘合沒有達到我們預期的效果,這就是粘包現(xiàn)象。
粘包
粘包是一種現(xiàn)象,而且只有tcp會出現(xiàn)粘包現(xiàn)象,udp不會,這是基于tcp的
流式傳輸
導致的,tcp是傳輸數(shù)據(jù)流。
tcp會將數(shù)據(jù)量較小,且發(fā)送時間間隔較短的數(shù)據(jù)一起打包發(fā)送,那么這里所講的時間較短是相比網(wǎng)絡(luò)延遲來說的。比如我們兩次發(fā)送間隔為0.00001s,那么網(wǎng)絡(luò)延遲為0.001s,這個時候兩次的數(shù)據(jù)就會打包發(fā)送,這是一種優(yōu)化機制,但也就是這個優(yōu)化機制導致粘包現(xiàn)象。
首先我們需要了解一下socket收發(fā)數(shù)據(jù)的原理:
發(fā)送端可以是1K1K地發(fā)送數(shù)據(jù),而接收端的應用程序可以兩K兩K地提走數(shù)據(jù),當然也有可能一次提走3K或6K數(shù)據(jù),或者一次只提走幾個字節(jié)的數(shù)據(jù),也就是說,應用程序所看到的數(shù)據(jù)是一個整體,或說是一個流(stream),一條消息有多少字節(jié)對應用程序是不可見的,因此TCP協(xié)議是面向流的協(xié)議,這也是容易出現(xiàn)粘包問題的原因。
而UDP是面向消息的協(xié)議,每個UDP段都是一條消息,應用程序必須以消息為單位提取數(shù)據(jù),不能一次提取任意字節(jié)的數(shù)據(jù),這一點和TCP是很不同的。怎樣定義消息呢?可以認為對方一次性write/send的數(shù)據(jù)為一個消息,需要明白的是當對方send一條信息的時候,無論底層怎樣分段分片,TCP協(xié)議層會把構(gòu)成整條消息的數(shù)據(jù)段排序完成后才呈現(xiàn)在內(nèi)核緩沖區(qū)。
例如基于tcp的套接字客戶端往服務端上傳文件,發(fā)送時文件內(nèi)容是按照一段一段的字節(jié)流發(fā)送的,在接收方看來,根本不知道該文件的字節(jié)流從何處開始,在何處結(jié)束。
所謂粘包問題主要還是因為接收方不知道消息之間的界限,不知道一次性提取多少字節(jié)的數(shù)據(jù)所造成的。
此外,發(fā)送方引起的粘包是由TCP協(xié)議本身造成的,TCP為提高傳輸效率,發(fā)送方往往要收集到足夠多的數(shù)據(jù)后才發(fā)送一個TCP段。若連續(xù)幾次需要send的數(shù)據(jù)都很少,通常TCP會根據(jù)優(yōu)化算法把這些數(shù)據(jù)合成一個TCP段后一次發(fā)送出去,這樣接收方就收到了粘包數(shù)據(jù)。
粘包解決
很遺憾,socket并沒有給我們提供內(nèi)置解決方法。
那我們需要如何解決?
問題的根源在于,接收端不知道發(fā)送端將要發(fā)送的字節(jié)流的長度。
我們可以基于此點想解決辦法,如何讓接收端知道發(fā)送端將要發(fā)送的字節(jié)流長度(提前獲知)?
我們可以在發(fā)送端寫一個提前告知的代碼,并且在接收端循環(huán)判定,是否達到預定字節(jié)流長度,達到了再一并打印出來:
發(fā)送端和接收端(關(guān)鍵)要結(jié)合起來看:
接下來我把源碼放上來,我加了一些判斷條件:
演示一下結(jié)果:
審核編輯:劉清
-
編解碼
+關(guān)注
關(guān)注
1文章
140瀏覽量
19614 -
字符串
+關(guān)注
關(guān)注
1文章
578瀏覽量
20506 -
網(wǎng)絡(luò)編程
+關(guān)注
關(guān)注
0文章
71瀏覽量
10074 -
TCP協(xié)議
+關(guān)注
關(guān)注
1文章
91瀏覽量
12070
發(fā)布評論請先 登錄
相關(guān)推薦
評論