本帖最后由 VisualEleven 于 2010-10-24 11:22:18 编辑

解决方案 »

  1.   

    补充一下,启动客户端,
    当调试服务端,断点设在while循环体内时,while循环体不会进入死循环。
    当运行服务端时,while就进入死循环。
      

  2.   

    while(bytes<=me.nLen)
    {
      ret=recv(socket,buf+bytes,me.nLen-bytes,0);
      bytes+=ret;
    }
      

  3.   

    struct Message
    {
      long nType;//消息类型
      long nLen;//数据的长度
      char *msg;
    }
      

  4.   

    觉得while(bytes!=me.nLen)也没问题啊
    保证接收me.nLen长度的字符串
      

  5.   

    你先调试一下服务器端接收到的me.nLen对不对!还有,你客户端发送的时候应该也用循环发送,以保证你发送的是你指定的长度!
      

  6.   

    发现了问题出在
    ret=recv(socket,buf+bytes,me.nLen-bytes,0);
    recv调用失败返回了-1;所以进入了无限循环。
    GetLasterError()返回10035,当前操作还没完成。是不是由于先发送了头,服务端接收到头后,再读取数据,
    由于头和数据分开发,数据段还未收到,
    所以recv(socket,buf+bytes,me.nLen-bytes,0)调用失败
    返回了-1;
      

  7.   

    如果按你这么说,可以在recv后面加一句 if(ret == -1) continue但是,我有疑问,一般没接到数据会阻塞在那里啊,怎么会返回-1呢,是不是发送端有什么问题?还有,你用的是非阻塞还是阻塞?
      

  8.   

    你接收到数据包头不就知道了后续的数据的字节大小了,你后面的while循环接收指定大小的字节数不就可以了,还有你没有必要包头和数据分别发,一起发就可以了
      

  9.   

    你接收到数据包头不就知道了后续的数据的字节大小了,你后面的while循环接收指定大小的字节数不就可以了,还有你没有必要包头和数据分别发,一起发就可以了
      

  10.   


    你用的是非阻塞的socket吧
    使用非阻塞的socket应该在recv之前先用select判断下是否有数据可读
      

  11.   


    我用的是WSAAsyncSelect模型,如何用select判断判断下是否有数据可读。
    while循环应该如何写呢?
    采用11楼的方法程序运行正常(可以在recv后面加一句 if(ret == -1) continue)
    但如果recv()在一段时间内一直返回ret的话,那么在该时间段内不就一直会执行while循环体?
      

  12.   

    还想问下,ret=recv(socket,buf+bytes,me.nLen-bytes,0);
    recv调用失败返回了-1;
    GetLasterError()返回10035,当前操作还没完成。出现上面情况是不是客户端的发的数据还没到达服务端呢?
      

  13.   

    WSAAsyncSelect的话在FD_READ中进行读取,当recv失败后,错误码为10035时就不要再循环去读了,这时表示缓冲区中已经没有数据了,等待下次FD_READ消息触发后再去读,当然你可以把每次recv到的东西保存到另一个地方,等确定已经收完一个完整的包了,再去解析
      

  14.   


    int ret,bytes=0;
    char buf[1024];
    while(bytes!=me.nLen)
    {
    ret=recv(socket,buf+bytes,me.nLen-bytes,0);
    if(ret == SOCKET_ERROR)
    {
    if (WSAGetLastError() == WSAEWOULDBLOCK) continue;
    else break;//接收出现错误,必须退出了。
    }
      bytes+=ret;
    }
      

  15.   

    这是异步IO模型必须处理的情况,你对任何一个socket操作,首先需要根据ret val来判断是否成功,成功则进行数据处理,否则就要进行异常处理。不能只顾接收,你都不知道接收的内容是不是你需要的或者说接收是否成功等。基本的东西还是需要花点时间学习的,潜心一个月包你成为WINSOCK高手。
      

  16.   

    WSAAsyncSelect模型就不推荐学习了,直接学习WSAEventSelect模型或者overlapped Io/IOCP模型,或者最基本的select模型都行,个人觉得WSAAsyncSelect模型没有应用价值。消息通信是他的一大性能限制。