第乙個需要討論的大概就是粘包問題了。因為這個是tcp的個性問題,udp通訊時不存在這個問題的。首先看一下什麼叫粘包:
客戶端採取與伺服器的長連線方式建立通訊(open-write/read-write/read-……-write/read-close)。即建立連線之後進行多次讀寫操作,最後才關閉。而且不是檔案傳輸,而是資料結構的傳輸(檔案傳輸發生粘包與沒發生粘包都不會影響結果,反正都是位元組流的按順序寫入本地檔案)。舉個例子來說明一下吧:
兩種資料結構: 則粘包是則是接受到 這個算是讓伺服器傻眼了,沒見過這麼詭異的資料結構,不知道怎麼處理了。
上面的例子是轉的網上的
來分析一下之所以發生粘包的原因吧,其實也就是為什麼tcp會發生,但是udp卻不會發生的原因:tcp是面向連線流式無邊界的傳輸方式。當傳輸通道建立之後,則資料流就像水一樣流過來,其中沒有資料邊界的概念,包隨便多大,因而會出現多個包最後粘成乙個大包。當然這個是tcp的原因,還有就是緩衝區機制的問題,傳送端在預設狀況下是需要等到傳送去滿才傳送出去,故而適當使用push刷緩衝區也可減少粘包的現象,還有就是接受緩衝區處理不及時,沒有做到來乙個包立馬處理完這個包。
所以解決的思路大約如下:
對於傳送方引起的粘包現象,使用者可通過程式設計設定來避免,
tcp提供了強制資料立即傳送的操作指令
push
,tcp
軟體收到該操作指令後,就立即將本段資料傳送出去,而不必等待傳送緩衝區滿。此種方法關閉了優化演算法,降低了網路傳送效率,影響應用程式的效能。而且並不能保證
100%
不發生粘包現象。
對於接收方引起的粘包,則可通過優化程式設計、精簡接收程序工作量、提高接收程序優先順序等措施,使其及時接收資料,從而盡量避免出現粘包現象。該種思路對於接收方的程式演算法結構要求較高,而且可靠性不高,因為網路通訊中的併發等現象大量存在,很難真的能完全即使處理接受緩衝區而不發生粘包。
由接收方控制,將一包資料按結構字段,人為控制分多次接收,然後合併,通過這種手段來避免粘包。該思路的問題就更大了,應用程式效率被降低太多。而且我實在不認為這個真能不發生粘包,雖然包變小了,但是併發情況的存在並不能保證接收方有足夠的間隙去處理包。
預定義資料結構,單執行緒。位元組流前面先加上包頭標誌位,包頭中包含該包的資料長度,這樣在讀取的時候可按位元組讀取。這樣可有效控制粘包問題。並可以成功避免殘包的問題,且不會發生連鎖反應,乙個壞包的出現不會影響下乙個包的正常讀取。如。該中解決方案的優點是可以保證通訊的100%準確,缺點是影響程式效能,因為按位元組讀取包,必定會影響程式的效率。
改進:預定義資料結構,單執行緒。但是不是按位元組。檢視頭標誌位,讀取包長度,檢視緩衝區內包長度,兩者相等,則直接讀取。如果緩衝區內可讀位元組數大於標誌位描述的包長度,則按照標誌位描述的包長度讀取資料,如果緩衝區內刻度位元組數小於標誌位描述的包長度,則執行緒睡眠,等下乙個資料報的到來。
預定義資料結構,多執行緒。伺服器端與客戶端都是多執行緒工作,客戶端為三個主要執行緒:傳送執行緒、讀取執行緒與解析執行緒。伺服器端為四個主要執行緒:監聽主線程、接收、讀取、解析。按照第五種的思路,拿到資料報之後直接扔給解析執行緒,解析執行緒負責資料解析以及最終結果的**。此處比第五種多的思路就是乙個多執行緒,從而可以很大幅度提公升程式的效能。
預定義資料結構示意圖:
標誌位長度
資料
TCP網路傳輸「粘包」問題
原文出處 http www.ciw.com.cn 當前在網路傳輸應用中,廣泛採用的是tcp ip通訊協議及其標準的socket應用開發程式設計介面 api tcp ip傳輸層有兩個並列的協議 tcp和udp。其中tcp transport control protocol,傳輸控制協議 是面向連線的...
TCP網路傳輸 粘包 問題
解決tcp網路傳輸 粘包 問題http www.ciw.com.cn 當前在網路傳輸應用中,廣泛採用的是tcp ip通訊協議及其標準的socket應用開發程式設計介面 api tcp ip傳輸層有兩個並列的協議 tcp和udp。其中tcp transport control protocol,傳輸控...
TCP連線時CSocket粘包問題的解決方法
解決tcp網路傳輸 粘包 問題 原文出處 http www.ciw.com.cn 當前在網路傳輸應用中,廣泛採用的是tcp ip通訊協議及其標準的socket應用開發程式設計介面 api tcp ip傳輸層有兩個並列的協議 tcp和udp。其中tcp transport control protoc...