文章出處: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