Send()不发送所有字节

send() not deliver all bytes?

本文关键字:字节 Send      更新时间:2023-10-16

为什么winsock中的send()不能保证您请求的所有字节的交付?

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

类似地,非阻塞时也会发生这种情况。你怎么能保证你把所有的东西都寄了?

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

如果没有发送所有内容,只需再次调用send即可。如果阻塞,你可以马上做。如果是非阻塞的,您可以等待或使用套接字发现方法(如select或I/O完成端口)。recv也是如此。如果你没有得到你想要的,再打电话给recv。这就是recvsend返回发送或接收字节数的原因之一。

传递给sendrecv的字节数只是一个限制。它可以发送少于这个数的数据(不过,除非是非阻塞的,否则通常不会)。但它肯定能接收到更少的信号。(操作系统无法控制它接收多少数据或何时接收数据。)

TCP为您实现。但是,如果您有一个涉及应用程序级消息的应用程序协议,那么应用程序必须实现它们。这不会奇迹般地发生。TCP不会为您"将字节粘合在一起"到消息中。TCP是字节流协议,而不是消息协议。如果你想要消息,你必须实现它们。

这个行为是"by design".

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

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);
  }

send告诉您它能够通过返回值发送什么。循环直到send累计发送完所有数据或返回一个错误。