今天就跟大家聊聊有關怎么處理tcp粘包問題,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)從2013年開始,先為武義等服務建站,武義等地企業(yè),進行企業(yè)商務咨詢服務。為武義企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。
tcp粘包問題處理的方法:1、定長發(fā)送法,發(fā)送端在發(fā)送數(shù)據(jù)時都以LEN為長度進行分包;2、尾部標記序列法,在每個要發(fā)送的數(shù)據(jù)包的尾部設置一個特殊的字節(jié)序列;3、頭部標記分步接收法,定義一個用戶報頭,在報頭中注明每次發(fā)送的數(shù)據(jù)包大小。
tcp粘包問題處理的方法:
1、設計方案一:定長發(fā)送
在進行數(shù)據(jù)發(fā)送時采用固定長度的設計,也就是無論多大數(shù)據(jù)發(fā)送都分包為固定長度(為便于描述,此處定長為記為LEN),也就是發(fā)送端在發(fā)送數(shù)據(jù)時都以LEN為長度進行分包。這樣接收方都以固定的LEN進行接收,如此一來發(fā)送和接收就能一一對應了。分包的時候不一定能完整的恰好分成多個完整的LEN的包,最后一個包一般都會小于LEN,這時候最后一個包可以在不足的部分填充空白字節(jié)。
當然,這種方法會有缺陷。
1.最后一個包的不足長度被填充為空白部分,也即無效字節(jié)序。那么接收方可能難以辨別這無效的部分,它本身就是為了補位的,并無實際含義。這就為接收端處理其含義帶來了麻煩。當然也有解決辦法,可以通過增添標志位的方法來彌補,即在每一個數(shù)據(jù)包的最前面增加一個定長的報頭,然后將該數(shù)據(jù)包的末尾標記一并發(fā)送。接收方根據(jù)這個標記確認無效字節(jié)序列,從而實現(xiàn)數(shù)據(jù)的完整接收。
2.在發(fā)送包長度隨機分布的情況下,會造成帶寬浪費。比如發(fā)送長度可能為 1,100,1000,4000字節(jié)等等,則都需要按照定長最大值即4000來發(fā)送,數(shù)據(jù)包小于4000字節(jié)的其他包也會被填充至4000,造成網(wǎng)絡負載的無效浪費。
綜上,此方案適在發(fā)送數(shù)據(jù)包長度較為穩(wěn)定(趨于某一固定值)的情況下有較好的效果。
2、設計方案二:尾部標記序列
在每個要發(fā)送的數(shù)據(jù)包的尾部設置一個特殊的字節(jié)序列,此序列帶有特殊含義,跟字符串的結束符標識”\0”一樣的含義,用來標示這個數(shù)據(jù)包的末尾,接收方可對接收的數(shù)據(jù)進行分析,通過尾部序列確認數(shù)據(jù)包的邊界。
這種方法的缺陷較為明顯:
1.接收方需要對數(shù)據(jù)進行分析,甄別尾部序列。
2.尾部序列的確定本身是一個問題。什么樣的序列可以向”\0”一樣來做一個結束符呢?這個序列必須是不具備通常任何人類或者程序可識別的帶含義的數(shù)據(jù)序列,就像“\0”是一個無效字符串內容,因而可以作為字符串的結束標記。那普通的網(wǎng)絡通信中,這個序列是什么呢?我想一時間很難找到恰當?shù)拇鸢浮?/p>
3、設計方案三:頭部標記分步接收
這個方法是作者有限學識里最好的辦法了。它既不損失效率,還完美解決了任何大小的數(shù)據(jù)包的邊界問題。
這個方法的實現(xiàn)是這樣的,定義一個用戶報頭,在報頭中注明每次發(fā)送的數(shù)據(jù)包大小。接收方每次接收時先以報頭的size進行數(shù)據(jù)讀取,這必然只能讀到一個報頭的數(shù)據(jù),從報頭中得到該數(shù)據(jù)包的數(shù)據(jù)大小,然后再按照此大小進行再次讀取,就能讀到數(shù)據(jù)的內容了。
這樣一來,每個數(shù)據(jù)包發(fā)送時都封裝一個報頭,然后接收方分兩次接收一個包,第一次接收報頭,根據(jù)報頭大小第二次才接收數(shù)據(jù)內容。(此處的data[0]的本質是一個指針,指向數(shù)據(jù)的正文部分,也可以是一篇連續(xù)數(shù)據(jù)區(qū)的起始位置。因此可以設計成data[user_size],這樣的話。)
下面通過一個圖來展現(xiàn)設計思想。
由圖看出,數(shù)據(jù)發(fā)送多了封裝報頭的動作;接收方將每個包的接收拆分成了兩次。
這方案看似精妙,實則也有缺陷:
1.報頭雖小,但每個包都需要多封裝sizeof(_data_head)的數(shù)據(jù),積累效應也不可完全忽略。
2.接收方的接收動作分成了兩次,也就是進行數(shù)據(jù)讀取的操作被增加了一倍,而數(shù)據(jù)讀取操作的recv或者read都是系統(tǒng)調用,這對內核而言的開銷是一個不能完全忽略的影響,對程序而言性能影響可忽略(系統(tǒng)調用的速度非常快)。
優(yōu)點:避免了程序設計的復雜性,其有效性便于驗證,對軟件設計的穩(wěn)定性要求來說更容易達標。綜上,方案三乃上上策!
看完上述內容,你們對怎么處理tcp粘包問題有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。