通过man page of the Linux system call sendfile
阅读,我想知道调用程序是否有可能知道in_fd
何时处于EOF状态。据推测,这可以通过返回值0来表示,但这会导致0的返回值实际意味着什么的问题。如果sendfile
与write
类似,则返回值0只表示复制了0个字节。但是,如果sendfile
与read
类似,则返回值0表示EOF。必须事先知道从in_fd
到out_fd
要复制多少字节才能使用sendfile
? sendfile
返回0时意味着什么?
答案 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)
重点是使用F_SETLEASE获取应用程序的文件租约。