【问题标题】:Understanding sendfile() and splice()了解 sendfile() 和 splice()
【发布时间】:2012-01-27 09:59:09
【问题描述】:

sendfile() 可用于将数据从“文件”描述符传输到“套接字”描述符,以便从机器 A 获取数据到机器 B。是否可以从“ socket”描述符到具有类似零拷贝语义的文件?我认为sendfile() 在这里没有帮助,因为sendfile() 需要数据源是“页面/缓冲区”缓存。我的理解正确吗? splice() 可以在这种情况下提供帮助吗?

【问题讨论】:

    标签: linux splice sendfile


    【解决方案1】:

    您对sendfile 的限制是正确的。是的,splice 可以提供帮助,但这并非微不足道:splice 要求至少有一个源文件描述符或目标文件描述符是管道。所以你不能直接splice从一个socket到一个普通的文件描述符。

    从概念上讲,您可以做的事情是:

    • 像往常一样设置入站套接字 fd 和输出文件 fd
    • pipe(2)创建一个管道
    • 在一个循环中:
      • 使用splice从套接字读取到管道的写入端
      • splice也从管道的读取端写入文件

    重复最后的步骤,直到读取所有数据。

    Zero-Copy in Linux with sendfile() and splice() 实现了这种技术。

    【讨论】:

    • 从 2.6.33 开始,sendfile 的 out_fd 可以是任何文件描述符(不仅仅是套接字)。
    • 从 4.2 开始,splice() 也是如此
    • @techno 我可以找到 splice() 的手册页仍然说 fd_in 或 fd_out 需要是一个管道。你有参考吗?
    • @technosaurus that commit 处理从 unix 域套接字 到管道 的拼接,因此与该声明不矛盾,而 splice 实际上确实如此(今天,在内核 5.1.3 中)仍然需要 fd_in 或 fd_out(或两者)作为管道
    猜你喜欢
    • 2015-08-01
    • 2011-11-09
    • 2011-01-04
    • 2015-07-07
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2016-06-09
    • 2013-09-15
    相关资源
    最近更新 更多