如何使用recv()接收大数据?

Mr.*_*ool -1 c++ sockets tcp client-server tcpsocket

我使用c ++开发了客户端服务器程序,所以我希望收到超过500kb,我的客户端消息以"!"结束 ,所以我想收到,直到我的最后一个字节(!)收到,这是我的代码,它不起作用.它有什么问题.

do
  {
  int num = recv(*csock,  buf, bytesLeft,0);

if (num == 0)
{
  break;
}
else if (num < 0 && errno != EINTR)
{
  fprintf(stderr, "Exit %d\n", __LINE__);
  exit(1);
}
else if (num > 0)
{
  numRd += num;
  buf += num;
  bytesLeft -= num;
  fprintf(stderr, "read %d bytes - remaining = %d\n", num, bytesLeft);
}

  }

    while (bytesLeft != 0);
   fprintf(stderr, "read total of %d bytes\n", numRd);
Run Code Online (Sandbox Code Playgroud)

Jas*_*son 6

虽然由于问题的措辞,我不确定你的问题究竟是什么,但你通常不能用它strcat来附加通过网络接收的原始缓冲区,除非你明确知道它们将被NULL终止,即便如此,那也不是如果您收到意外的数据传输,真的"安全".使用c-strings的假设是它们以NULL结尾,但是原始网络缓冲区可能不是,并且strcat如果不是以NULL结尾,则使用将导致输入缓冲区溢出.而不是strcat使用大小为N字节的已知固定大小的缓冲区来接收数据,并通过缓冲区递增临时指针,直到到达缓冲区的末尾或数据包传输结束.这样,您将始终从网络读取多达N个字节而不再读取,并防止发生缓冲区溢出情况.

例如,您可以执行以下操作(由于所有复制,这不是最快或更有效的解决方案,但它有效):

unsigned char buf[10000];  //10Kb fixed-size buffer
unsigned char buffer[MAXRECV];  //temporary buffer

unsigned char* temp_buf = buf;
unsigned char* end_buf = buf + sizeof(buf);

do
{       
    iByteCount = recv(GetSocketId(), buffer,MAXRECV,0);   

    if ( iByteCount > 0 )
    {
        //make sure we're not about to go over the end of the buffer
        if (!((temp_buf + iByteCount) <= end_buf))
            break;

        fprintf(stderr, "Bytes received: %d\n",iByteCount);
        memcpy(temp_buf, buffer, iByteCount);
        temp_buf += iByteCount;
    }
    else if ( iByteCount == 0 )
    {
        if(temp_buf != buf)
        {
            //do process with received data
        }
        else
        {
            fprintf(stderr, "receive failed");
            break;
        }
    }
    else
    {
        fprintf(stderr, "recv failed: ");
        break;
    }
} while(iByteCount > 0 && temp_ptr < end_buf);  //check for end of buffer
Run Code Online (Sandbox Code Playgroud)