理解sendfile()和splice()

use*_*946 7 linux splice sendfile

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

Mat*_*Mat 13

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

从概念上讲,你可以做的是:

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

重复上一步,直到读取所有数据.

使用sendfile()和splice()在Linux中进行零复制具有此技术的实现.

  • 从2.6.33开始,sendfile的out_fd可以是任何文件描述符(不仅仅是套接字). (4认同)
  • @technosaurus 提交处理从 unix 域套接字 _to pipeline_ 的拼接,因此与该语句并不矛盾,并且 splice 事实上(今天,在内核 5.1.3 中)仍然需要 fd_in 或 fd_out (或两者)成为管道 (3认同)
  • 从 4.2 开始,`splice()` 也是如此 (2认同)
  • @techno 我可以找到“splice()”的手册页仍然说 fd_in 或 fd_out 需要是一个管道。你有参考吗? (2认同)