天天看點

TCP 包完整性檢驗

文章出處:http://www.emlog.net/nemo/post-18.html

我沒有用UDP編過程式,但是我看見過很多區域網路遊戲都是使用UDP。特别是對于實時響應一些要求很高的FPS來說,它們的發包量通常不大,但是需要很快的傳輸和響應速度。相反,大型的網絡遊戲通常都是用TCP。顯而易見的是,因為廣域網的遊戲需要有一個更可高的網絡傳輸環境。

我寫的網絡程式都是基于TCP的。不過,TCP雖然能夠保證資料完整的收到,但是并不保證應用程式在每次調用recv()函數時收到的是一個完整的資料包。也就是說,可能會因為網絡的各種狀況導緻隻收到一次收到半個包或者超過1個包的資料。比如程式三次recv()收到的資料是這樣的。

第一次:[a][a][a][a][a][b][b]

第二次:[b][b][b][c][c][c]

第三次:[c][c][d][d]

……

這時就需要對程式做包的完整性檢測了,下面提供一個包完整性檢測的僞代碼,是公司的一位前輩教我的。說是僞代碼,其實已經跟實際的代碼差不多了。

//包完整性檢測的僞代碼

const int iNums=65536;

int buflen = 0

char Buffer[iNums];

bool succRec=fasel;

int len=recv()

memcpy(Buffer,recv_buf,len);

buflen += len;

if (buflen > Package_size)

{

   memcpy(Package,Buffer,Package_size); 

   memmove(Buffer,&Buffer[Package_size],Package_size);

   buflen -= Package_size;

   succRec=true;

}

if(succRec)

{

Process(Package);

}

這樣的話,第一次收到資料并處理包後的緩沖區是:[b][b]

第二次就是:[c][c][c]

第三次就是:[d][d]

這樣,收到三個包就都是完整而且可處理的了。

idnemo 2008-07-15 14:44 memcpy把已經收到的資料部分儲存,然後使用memmove将Buffer緩沖區的指針前移,前移位置量是Package_size,是以應是一個Package_size大小.  ??? cai 2008-07-10 06:22 memmove(Buffer,&Buffer[Package_size],Package_size);

最後一個參數是否應改為:buflen -Package_size

繼續閱讀