send()不会传递所有字节?

时间:2013-01-18 13:09:18

标签: c++ networking tcp byte winsock

send()winsock为什么不保证您所请求的所有字节的传送?

这是TCP,它是阻塞套接字。

同样,这种情况发生在非阻塞时。你怎么能保证你发送所有东西?

我注意到recv()做同样的事。

3 个答案:

答案 0 :(得分:7)

如果它没有发送所有内容,只需再次呼叫send。如果阻止,您可以立即执行。如果是非阻塞的,您可以等待或使用套接字发现方法(如select或I / O完成端口)。 recv也是如此。如果您没有得到所需的全部内容,请再次致电recv。这是recvsend返回发送或接收的字节数的原因之一。

您传递给sendrecv的字节数只是一个限制。它可以发送少于那个(但是,除非非阻塞,通常不会)。但它绝对可以获得少于此。 (操作系统无法控制接收的数据量或接收数据的数量。)

为您实施TCP。但是,如果您的应用程序协议涉及应用程序级别的消息,那么应用程序必须实现它们。它不会发生魔术。 TCP不会将“将字节粘合在一起”为您的消息。 TCP是字节流协议,而不是消息协议。如果你想要消息,你必须实现它们。

答案 1 :(得分:5)

此行为是“按设计”。

您可以使用外部循环,如下例所示:

int sendBuffer (SOCKET ClientSocket, const char *buf, int len, int flags) 
  {
    int num_left = len;
    int num_sent;
    int err = 0;
    const char *cp = buf;

    while (num_left > 0) 
      {
        num_sent = send(ClientSocket, cp, num_left, flags);

        if (num_sent < 0) 
          {
            err = SOCKET_ERROR;
            break;
          }

        assert(num_sent <= num_left);

        num_left -= num_sent;
        cp += num_sent;
      }

    return (err == SOCKET_ERROR ?  SOCKET_ERROR : len);
  }

答案 2 :(得分:0)

send告诉您它能够通过其返回值发送的内容。 循环直到send累积发送所有数据或返回错误。