Re: [問題] winsock網路程式
recv() 會回傳收到資訊的大小值,如有錯誤,會回傳負數值
我以前都是寫
char buffer[32767]; // 大小自訂
len=recv(socket, buffer, sizeof(buffer), 0 )
if (len>0)
{
//讀取封包內容,注意長度為 len
}
理論上傳回的封包不可能有錯。TCP/UDP 傳輸中途有錯的話都是在系統底層就解決掉了。
application 層應該是可以安心使用
※ 引述《MLP2007.bbs@ptt.cc (NEW)》之銘言:
> ※ 引述《Devil.bbs@bbs.csie.ncku.edu.tw (璉璉)》之銘言:
> : 不完全了解你的意思。
> : 我想你應該是一收到資料就開始處理,通常在這時候還沒收全,所以有了時間差才會
> : 有影響...
> : 自定通訊協定時,應該要有溝通的方式,比如說先送位元陣列長度,在收資料時,去
> : 檢查資料是否已達指定長度後再處理。
> 我的想法:
> 把socket設為block mode
> 若Data還沒收全 則程式會block在recv中
> 如果recv回傳為SOCKET_ERROR代表有錯誤
> 否則即代表buffer已經填好資料可以讀取了
> 這樣說對不對?
> 我的寫法大概如下
> UINT FileReceiveThread(LPVOID pParam) //Receive Thread Function
> {
> struct Packet pak;
> REGET:
> do{
> if(recv(sock, (char*) &pak, sizeof(struct Packet), 0) == SOCKET_ERROR)
> {
> // recv error
> return 0;
> }
我猜您遇到問題的原因是:
照您這樣寫看起來是為了一次只讀取一個 struct Packet 的大小以方便程式撰寫
但是要注意,TCP底層並不知道你的資料傳到哪裡算是一個 Packet
所以你可能在某一次收到的 pak 長度 < sizeof(struct Packet)
這個情況在您定義 sizeof (struct Packet) > 4096(印象中正常TCP frame的大小)
時很可能發生
但 < 4096 也不一定可以一次收滿。
因此還是要先存到一個 Buffer 再作切割,像是上面的寫法。
> if(!strcmp(pak.type, IDENTIFY_STRING))
> {
> //Correct Data Packet
> fwrite(pak.buffer, sizeof(char), pak.datasize, pFile);
> }
> else
> {
> //Wrong Data Packet
> goto REGET;
> }
> }while(pak.datasize == BUFFER_SIZE);
> }
> 請多指教.
如有錯誤請更正,謝謝
--
夫兵者不祥之器物或惡之故有道者不處君子居則貴左用兵則貴右兵者不祥之器非君子
之器不得已而用之恬淡為上勝而不美而美之者是樂殺人夫樂殺人者則不可得志於天下
矣吉事尚左凶事尚右偏將軍居左上將軍居右言以喪禮處之殺人之眾以哀悲泣之戰勝以
喪禮處之道常無名樸雖小天下莫能臣侯王若能守之萬物將自賓天地相合以降甘露民莫
之令而自均始制有名名亦既有夫亦將知止知 218-163-129-105.dynamic.hinet.net海
討論串 (同標題文章)
Programming 近期熱門文章
PTT數位生活區 即時熱門文章