【问题标题】:With sendfile(), is it possible to tell when in_fd is at EOF?使用 sendfile(),是否可以判断 in_fd 何时处于 EOF?
【发布时间】:2011-04-11 10:51:58
【问题描述】:

阅读man page of the Linux system call sendfile,我想知道调用程序是否有可能知道in_fd 何时处于EOF。据推测,这可以通过返回值 0 来表示,但这会导致返回值 0 的实际含义的问题。如果sendfilewrite 类似,则返回值0 仅表示复制了0 个字节。但是,如果 sendfileread 类似,则返回值 0 表示 EOF。必须事先知道要从in_fd 复制多少字节到out_fd 才能使用sendfilesendfile返回0是什么意思?

【问题讨论】:

    标签: c linux eof sendfile zero-copy


    【解决方案1】:

    在我的情况下,遇到文件被rsync截断,应用程序同时使用sendfile传输文件。我发现应用程序在这种情况下吃 cpu 100%,我修复了我的代码参考下面的文章,问题消失了。 http://www.linuxjournal.com/article/6345

    关键是使用 F_SETLEASE 为您的应用获取文件租约。

    【讨论】:

      【解决方案2】:

      当发送的字节数为 0 时,您可以假设已达到 EOF:

      sent = sendfile(out_fd, in_fd, &offset, nbytes);
      if (sent == 0) {
          // EOF
          ...
      }
      

      这种假设也适用于非阻塞套接字。

      【讨论】:

      • 没有记录。我自己直接验证了。
      【解决方案3】:

      您可以使用偏移参数来进行读取计数。

      根据手册页

      如果 offset 不为 NULL,则它指向一个保存文件偏移量的变量,sendfile() 将从该文件偏移量开始从 in_fd 读取数据。当 sendfile() 返回时,此变量将设置为读取的最后一个字节之后的字节偏移量。如果offset不为NULL,则sendfile()不会修改in_fd的当前文件偏移量;否则调整当前文件偏移量以反映从 in_fd 读取的字节数。

      count 是要在文件描述符之间复制的字节数。

      返回值 如果传输成功,则返回写入 out_fd 的字节数。出错时,返回 -1,并正确设置 errno。

      是的,这意味着返回值 0 意味着没有数据复制到写入套接字。

      【讨论】:

        【解决方案4】:

        我认为没有任何直接的方法可以知道这一点,但这并不重要。通常你会通过stat/fstat 找到输入文件的大小,并用它来计算你的传输。插座端对您来说无关紧要。

        这应该是有问题的唯一情况是,如果您要传输正在增长或缩小的文件。鉴于输入文件必须经过 mmap 处理,并且在这些情况下使用 mmap 可能会发生坏事(没有一些巧妙的代码),您可能不应该在这些情况下使用 sendfile。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-10
          • 1970-01-01
          • 2010-10-13
          • 2021-03-31
          • 1970-01-01
          相关资源
          最近更新 更多