Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding sendfile() and splice()

sendfile() can be used to transmit data from a "file" descriptor to a "socket" descriptor in order to get data from machine A to machine B. Is it possible to get the data at the receiving end from the "socket" descriptor to a file with similar zero-copy semantics? I think sendfile() doesn't help here because sendfile() needs the source of data to be "page/buffer" cache. Is my understanding correct? Can splice() help in this situation?

like image 629
user880946 Avatar asked Dec 24 '11 18:12

user880946


People also ask

What is Sendfile?

In computing, sendfile is a command which can be found in a number of contexts relating to data transmission: Sendfile (Unix), a push-based asynchronous file transfer, regardless of whether local or remote, using the Simple Asynchronous File Transfer (SAFT), an Internet protocol bound to TCP port 487.

What is Sendfile Linux?

sendfile() copies data between one file descriptor and another. Because this copying is done within the kernel, sendfile() is more efficient than the combination of read(2) and write(2), which would require transferring data to and from user space.


1 Answers

You're correct about the limitation of sendfile for this. And yes, splice can help, but it's not trivial: splice requires that at least one of the source or target file descriptors be a pipe. So you can't directly splice from a socket to a plain file descriptor.

Conceptually, what you can do to make it work is:

  • setup your inbound socket fd and your output file fd as you would normally
  • create a pipe with pipe(2)
  • in a loop:
    • read from the socket to the write side of the pipe with splice
    • write from the read side of the pipe to the file with splice also

Repeat the last steps until all the data is read.

Zero-Copy in Linux with sendfile() and splice() has an implementation of this technique.

like image 114
Mat Avatar answered Oct 01 '22 08:10

Mat