網路遊戲資料傳輸 粘包的處理

2021-07-02 19:13:13 字數 2306 閱讀 4082

網路傳輸大體上包含這四個協議type area command message,這四層協議是依次向下傳遞的。

所謂協議,說簡單點就是伺服器端和客戶端的乙個約定,

比如,向伺服器傳送(1,0,1,「賬號:*** 密碼***」)

約定type中1代表登入模組,因為登陸不需要經過area協議,所以跳過area協議,直接到command協議,

command中1代表登陸,2代表註冊,3代表返回登陸結果,傳入的是1,故進行登陸邏輯,注意,如果type不是1,此處1,2,3就會代表別的東西了。

如果登陸成功,伺服器會返回(1,0,3,「true」)

如果不嫌麻煩,完全可以只定義乙個協議,但是估計沒人那麼做

在傳輸過程中,為了進行高效的傳輸,所有的資料都會連在一起,如果傳的是int a = 1 string b = 「qaz」傳輸時會變成1qaz

為了進行區分,通常會在傳輸資料體前用乙個8位元組的int傳入這個資料體的長度(一般乙個int就佔8個位元組),這個int通常叫做資料頭

如果想傳的資料佔256個位元組,那麼傳的時候會傳送256+8個位元組

如果想傳送乙個float和乙個bool,那麼真正傳送的會是連在一起的int float int bool

下面說下如何進行解析

在連線伺服器後,用beginreceive進行資料接收,其中乙個引數定義了快取大小

建立乙個位元組陣列byte[1024]來作為快取

建立乙個bytearray來儲存待處理資料,bytearray是可以改變大小的

當快取中收到資料時,會將資料加入到bytearray

之後,判斷是否正在進行資料處理,如果沒在則開始資料處理:

↓判斷bytearray長度是否大於8,即是否把記錄訊息體長度的int讀取完

若小於8,不做處理等待,下次接受

若大於8,使用readint讀取int

bytearray有乙個position屬性,預設為0,當執行readint時會從0下標讀到8下標,因為int位元組長度為8,所以就算bytearray裡有很多資料,就算有1024個位元組,readint也只會讀8位,之後position=8

舉個例子,如果傳入 1,2,3三個int 連續執行3次readint就會得到1,2,3

獲取資料體長度int l後,再判斷剩下的資料長度是否大於l,若大於則說明資料完整,建立新的arraylist2,從arraylist讀取8到8+l的內容,al的position+l

對arraylist2進行read,至於是readint還是readbytes,要按照協議進行,簡而言之,伺服器傳的順序要和收的順序一致

之後,我們建立乙個新的快取來儲存listarray position之後的資料,再使arraylist=這個新快取

再次執行"↓"之後的內容

//訊息體長度為乙個8位元組數值 長度不足的時候 說明訊息未接收完成 或者是廢棄訊息

if (iobuff.length < 8)

//讀取定義的訊息的長度

int datasize = iobuff.readint();

if (datasize > iobuff.length - 8)

//建立完整訊息體的動態陣列

bytearray iodata = new bytearray();

//從訊息快取中取出正確的訊息體 位元組陣列內容

iodata.writebytes(iobuff.buffer, 8, datasize);

iobuff.postion += datasize;

int type=iodata.readint();

int area=iodata.readint();

int command=iodata.readint();

byte cache=iodata.readbytes();

object message = acecode.code.acedecode(cache);

//轉換為傳輸模型用於使用

socketmodel model = new socketmodel(type, area, command, message);

//將訊息儲存進訊息列表 等待unity來讀取

messagelist.add(model);

//建立新快取區

bytearray bytes = new bytearray();

//將舊快取區的剩餘資料移動到新快取區

bytes.writebytes(iobuff.buffer, iobuff.postion, iobuff.buffer.length - iobuff.postion);

//更新快取區

iobuff = bytes;

ondata();

網路遊戲粘包處理

int tcpclient onrecv else return error void tcpclient decoderecvbuffer decodeoffset net packet head len 從池子裡面取出長度為datalen的m recievepacket 實際上就是乙個char ...

QT Go TCP資料傳輸粘包問題

使用go語言為伺服器,qt作為客戶端,利用tcp進行資料傳輸,當兩次傳送間隔過近會產生粘包現象,此時就需要乙個特定的資料格式用來區分兩個資料的邊界,我使用 特徵碼 int型別用來區分是否惡意 資料報大小 int 壓縮標誌 bool 資料 byte 但當互動時發生問題,比如qt的自定義資料格式qbyt...

網路資料傳輸

網路資料傳輸 wcdma全名是widebandcdma,中文譯名為 寬頻分碼多工訪問 它可支援384kbps到2mbps不等的資料傳輸速率,在高速移動的狀態,可提供384kbps的傳輸速率,在低速或是室內環境下,則可提供高達2mbps的傳輸速率。而gsm系統目前只能傳送9.6kbps,固定線路mod...