我的代码: timeval timeOut;
timeOut.tv_sec = 0;
timeOut.tv_usec = 3000*1000; fd_set fdread, fdExcept;
FD_ZERO(&fdread);
FD_ZERO(&fdExcept); 
FD_SET(sock,&fdread); //加入套接字
FD_SET(sock,&fdExcept);    int iRet = 0;
iRet = select(0, &fdread, NULL, &fdExcept, &timeOut); if(FD_ISSET(sock,&fdread)) //是否存在fread中
{
           //是可读的
   int iRecv = recv(sock, strRecv, 512*1024, 0);// extern char strRecv[512*1024]
           /*
              如果对方发送的数据比较小,比如1024 BYTE, recv可以正常接收,recv函数返回1024。但是如果对方发送的数据比较大,比如50*1024 BYTE,接收的数据就无法正常接收了。recv返回的值是一个小于50*1024的值。strRecv中的数据也不正确。但是如果不用select函数,只用recv进行阻塞接收的话,接收50K BYTE就正常了。
           */
}

解决方案 »

  1.   

    我觉得和我遇到的问题有点类似…………
    因该与缓冲区有关
    因为默认的接收缓冲区为8k,所以应该是循环接收的
    你可以尝试用setsockopt把接收缓冲区调到很大看看,我估计就正常了,呵呵
      

  2.   

    select只要有数据就是可读的,即使只收到一部分数据,select也会返回,所以recv有可能不能收到所有数据,此时要再select,然后再recv,循环直到收到所以数据
      

  3.   

    你用的是UDP socket 还是 TCP socket?
      

  4.   

    recv不一定能接受完整个包,多次recv,直到接收到的数据与发送的一样(或者recv不到为止)
      

  5.   

    // 这是我在程序启动时设置 接收缓冲区nRecvBuf=1024*1024;//设置为1MBiRet = setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));是不是当我用select函数时,还需要再设置一下缓冲区?
    fd_set fdread, fdExcept;
        FD_ZERO(&fdread);
        FD_ZERO(&fdExcept); 
        FD_SET(sock,&fdread); //加入套接字
        FD_SET(sock,&fdExcept);   
      

  6.   

    那就不用了
    在socket创建后设置就可以了
    那你就再次select,使程序循环进入recv接收应该可以的