看板Programming
标 题Re: [问题] winsock网路程式
发信站无名小站 (Tue Oct 31 00:59:36 2006)
转信站ptt!ctu-reader!ctu-peer!news.nctu!netnews.csie.nctu!wretch
recv() 会回传收到资讯的大小值,如有错误,会回传负数值
我以前都是写
char buffer[32767]; // 大小自订
len=recv(socket, buffer, sizeof(buffer), 0 )
if (len>0)
{
//读取封包内容,注意长度为 len
}
理论上传回的封包不可能有错。TCP/UDP 传输中途有错的话都是在系统底层就解决掉了。
application 层应该是可以安心使用
※ 引述《[email protected] (NEW)》之铭言:
> ※ 引述《[email protected] (琏琏)》之铭言:
> : 不完全了解你的意思。
> : 我想你应该是一收到资料就开始处理,通常在这时候还没收全,所以有了时间差才会
> : 有影响...
> : 自定通讯协定时,应该要有沟通的方式,比如说先送位元阵列长度,在收资料时,去
> : 检查资料是否已达指定长度後再处理。
> 我的想法:
> 把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海