粘包只可能出現在流傳輸中,tcp是基於流傳輸的,而udp是不會出現粘包,因為udp是基於報文的,也就是說udp傳送端呼叫幾次write,接收端必須呼叫相同次數的read讀完,每次最多只能讀取乙個報文,報文與報文是不會合併的,如果緩衝區小於報文長度,則多出來的部分會被丟掉。tcp不同了,它會合併訊息,並且以不確定方式合併,這樣就需要我們去粘包處理了,tcp造成粘包可能是傳送端也可能是接收端的原因。主要表現為收到的包不完整或者收到的包帶著其它包的全部或部分資料。但資料還是按順序的,不會出現包之間順序混合,只需要找到包的開頭和結尾進行組合就好了。
1、如果利用tcp每次傳送資料,就與對方建立連線,然後雙方傳送完一段資料後,就關閉連線,這樣就不會出現粘包問題(因為只有一種包結構,類似於http協議)。關閉連線主要要雙方都傳送close連線(參考tcp關閉協議)。如:a需要傳送一段字串給b,那麼a與b建立連線,然後傳送雙方都預設好的協議字元如"hello give me your message",然後b收到報文後,就將緩衝區資料接收,然後關閉連線,這樣粘包問題不用考慮到,因為大家都知道是傳送一段字元。
2、如果傳送資料無結構,如檔案傳輸,這樣傳送方只管傳送,接收方只管接收儲存就ok,也不用考慮粘包。
3、如果雙方建立連線,需要在連線後一段時間內傳送不同結構資料,如連線後,有好幾種結構:
a、"hello give me your message"
b、"don't give me your message"
這樣的話,如果傳送方連續傳送兩個這樣的包出去,接收方一次接收可能會是"hello give me abour your messagedon't give me abour your message",這樣接收方就傻眼了,到底應該怎麼分了?因為沒有協議規定怎麼拆分這段字串,所以要處理好分包,需要雙方組織乙個比較好的包結構,一般會在頭上加上訊息型別,訊息長度等以確保正常接收。
總結:長連線且發多種資料格式的情況下需要考慮分包。
1、訊息定長,報文大小固定長度,不夠空格補全,傳送和接收方遵循相同的約定,這樣即使粘包了通過接收方程式設計實現獲取定長報文也能區分。
2、包尾新增特殊分隔符,例如每條報文結束都新增回車換行符(例如ftp協議)或者指定特殊字元作為報文分隔符,接收方通過特殊分隔符切分報文區分。
3、將訊息分為訊息頭和訊息體,訊息頭中包含表示資訊的總長度(或者訊息體長度)的字段
4、新增包頭和包尾分隔符,不使用資料大小來分包。
這裡採用的是在訊息頭部和尾部分別新增標誌。
只有同時有包頭和包尾的訊息才是合法的。
//收到伺服器的訊息,分包處理,可以修改為設定包頭和包尾的標誌幀,而不是固定的$start$和$end$
//analysisdata 處理一包資料的函式
void dataprocess::handlerecvdata(qbytearray data)
}//start比end靠前,直接擷取一包
else
//查詢下一包
ipos = iend+5;
}else
}else
//之前有頭部則接著把它合併,沒有尾部資料接著組裝並返回,有尾部就去處理
else
//之前保留有頭部,現在有尾
else}}
}//while end
}
TCP粘包分包現象
服務端,接收資料,在每次接收到的資料末尾添上乙個 尾 字 客戶端傳送資料,將同樣的資料連續傳送若干次 不是將資料複製若干份一次傳送 using system using system.collections.generic using system.componentmodel using syst...
TCP原理 粘包分包現象
參考 雲棲社群 就是要你懂 tcp 最經典的tcp效能問題 粘包現象產生的原因 由於tcp協議本身的機制 三次握手 客戶端與伺服器會維持乙個連線 channel 資料在連線不斷開的情況下,可以持續不斷地將多個資料報發往伺服器,但是如果傳送的網路資料報太小,那麼他本身會啟用nagle演算法 可配置是否...
TCP以及TCP中的粘包與分包
1.tcp tcp 確認,重傳機制,按序到達 擁塞控制 防止過多的資料注入到網路中 流量控制 流量控制所要做的就是抑制傳送端傳送資料的速率,以便使接收端來得及接收 不同的協議層對資料報有不同的稱謂,在傳輸層叫做段 segment 在網路層叫做資料報 datagram 在鏈路層叫做幀 frame 採用...