使用sendfile(),是否可以判断in_fd何时处于EOF?

时间:2010-09-12 23:02:06

标签: c linux eof sendfile zero-copy

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

4 个答案:

答案 0 :(得分:4)

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

唯一可能存在问题的情况是,如果要传输正在增长或缩小的文件。鉴于输入文件必须是mmap-ed,并且在这些情况下使用mmap可能发生的坏事(没有一些聪明的代码),你可能不应该为这些情况使用sendfile。

答案 1 :(得分:3)

您可以使用offset参数进行读取计数。

根据Man页面

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

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

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

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

重点是使用F_SETLEASE获取应用程序的文件租约。