双方均为MFC CSOCKET的派生类,客户端发送数据,无论是10个字节也好,20个字节也好,服务器端总是4个字节一收.比如说如果我发20个字节,那它就OnReceive五次.我用sniffer看过,发确实在一个数据包里发的.只可能是收出了问题,而接收用的缓冲区足够大.
  我的每个数据包分两部分,前12个字节是自定义头部,中间有个字段指明了后面数据的长度.现在出现了上面的问题,我没法一次收完,但也不知道该怎么收.如果发的是正确的包,那我还可以先收头部(12字节),然后根据头部得到后面数据长度,再接收.但如果故意发个错误的包,就阻塞在那里了.
我试过用setsockopt设定接收缓冲区,但还是一次最多收4个字节;想把套接字设定成异步,用asyncselect将套接字设定成异步,用ioctl设FIONREAD,用setsockopt设SO_RCVTIMEO,函数都成功返回,但没有数据的时候仍然是阻塞在那里.我实在没有办法了.
现在程序的结构就这样了,不大可能不用CSOCKET的派生类.还有的救吗?

解决方案 »

  1.   

    代码比较乱,很难贴.但接收部分就这样的了:sock.Receive(pRcvBuf, sizeof(pRcvBuf), 0 );
    你说的不可能是不可能收4个字节,还是不可能改不成非阻塞?
      

  2.   

    服务器端总是4个字节接收,是你定的吗?默认也不止这么长的。那是因为你后边的参数不对,sizeof(pRcvBuf)是一个指针的大小,当然就是4个字节了,你其实应改成所定义指针所指的数组长度,或一个固定值,如128/256什么的,不要用sizeof(pRevBuf)了。
      

  3.   

    改成类似这样的代码试试#define BUF_SIZE 8192char pRcvBuf[BUF_SIZE]={0};sock.Receive(pRcvBuf, BUF_SIZE,0 );
      

  4.   

    如果pRcvBuf是像楼上这样的一个数组,那sizeof是没有问题的:sizeof(pRcvBuf)==BUF_SIZE;
    如果是类似char* pRcvBuf = new char[BUF_SIZE]这样,则sizeof(pRcvBuf)==4。
      

  5.   

    好的谢谢诸位,这个问题我改掉了,是上面说的原因.
    那阻塞非阻塞呢?从CSOCKET继承下来的能改成非阻塞吗?怎么改?
      

  6.   

    CSocket本来就是非阻塞的,但是其中利用了非阻塞的原理,在发送和接受的时候进行消息处理,比方说,在recv的时候,如果数据没有来,那么函数不会返回,但是进入一个消息循环,这个时候系统可以处理消息,当数据到来的时候,且长度是用户指定的长度,那么函数才会返回。建议看一下csocket的源码,就很清楚了。