【问题标题】:send() function in C how to handle if not all bytes are sent?如果未发送所有字节,C 中的 send() 函数如何处理?
【发布时间】:2012-12-20 11:42:11
【问题描述】:

我需要向套接字发送数据,基本上是传输一个文件,

根据 send() 函数文档,它说,

If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter. Otherwise, a value of SOCKET_ERROR is returned,

我担心的是,返回值可能小于请求值。 因为我正在读取文件并写入套接字,因为它可能不会发送所有字节,所以我想如果没有发送完整的缓冲区,我将不得不重试?在这种情况下,我想我必须以某种方式将同一缓冲区上的指针通过读取的字节提前并再次发送??

我只是想知道是不是这样?或者有什么更聪明的方法,这样所有请求的数据都会被发送,而我不必担心什么时候没有发送所有数据?

谢谢,

【问题讨论】:

  • 发送方和接收方进程都应该处理 TCP/IP 实现将数据分成块的情况。所以你可能需要做几个sendrecv,你应该关心结果。
  • 你会发现这种情况在阻塞模式下从来没有真正出现过,不管文档怎么说。 send() 阻塞,直到所有数据都传输到套接字发送缓冲区中。
  • @EJP 它可以在阻塞模式下出现。例如,如果信号处理程序中断了 send(),该 send() 已传输了部分数据,但不是全部。

标签: c sockets


【解决方案1】:

是的,您必须担心send(或write 等)返回的值。没有特别聪明的办法,但有几个函数是由优秀的 Richard Stevens 编写的,即readnwriten

This article on informit 似乎有这些函数的一个版本。

【讨论】:

    【解决方案2】:

    是的,您必须前进缓冲区指针并重复send 调用,直到整个缓冲区被消耗或出现硬错误。标准的成语看起来像这样:

    int
    send_all(int socket, const void *buffer, size_t length, int flags)
    {
        ssize_t n;
        const char *p = buffer;
        while (length > 0)
        {
            n = send(socket, p, length, flags);
            if (n <= 0)
                return -1;
            p += n;
            length -= n;
        }
        return 0;
    }
    

    请注意,如果您发送的数据报的边界很重要(例如 UDP),您不能使用这种技术;您必须将短发送视为失败。

    【讨论】:

      【解决方案3】:

      你可以试试这样的:

      int ret, bytes = 0;
      while (bytes < buflen) {
          ret = send(sock_fd, buf+bytes, buflen-bytes, flags);
          //check for errors
          if (ret == -1) {
              // handle error
          }
          bytes+=ret;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-13
        • 2013-01-02
        • 2019-04-29
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        相关资源
        最近更新 更多