1

In my software, I'm using a PF_UNIX-socket for IPC.

Until now I need to allocate a (pre-)buffer via malloc to prepare the data before writing it via write into the buffer.

Now I was wondering:

The socket-fd already has a buffer of eg. 64kb, so why can't I simply directly prepare & write my data into that buffer like in this way:

// stupid example-code, don't copy
void *fd_buffer = get_buffer_of_fd(fd)
fd_buffer[0] = 1
fd_buffer[1] = 2
fd_buffer[2] = 3
memcpy(fd_buffer, 5, 5)
...
commit_buffer_of_fd(fd, xbytes); // xBytes is DYNAMIC and not known until this point!!

If this would be possible, I could save the roundtrip of copying into the pre-buffer, writing into the socket from the pre-buffer and even allocate the pre-buffer.

Has anyone an idea if that is possible?

Martin L.
  • 3,006
  • 6
  • 36
  • 60
  • 1
    I am fairly sure what you want is not supported by anything. Also if the time it takes to copy data on a socket is such a big deal why don't you just use shared memory to communicate? It will be faster, cleaner and actually supported. – Alex Sep 10 '13 at 15:25
  • Thank you very much for your feedbacks. It's no big deal, I just searched for maybe better ways :-) As I'm on Android there is sadly no method for shared memory. Thank you very much! – Martin L. Sep 10 '13 at 15:33
  • Some exmaples on splicing: http://ogris.de/howtos/splice.html – alk Sep 10 '13 at 15:42
  • 1
    @MartinM. You sure? http://stackoverflow.com/questions/16099904/how-to-use-shared-memory-ipc-in-android http://elinux.org/Android_Kernel_Features#ashmem – Alex Sep 10 '13 at 15:43
  • Good hint, thank you I will analyze this :) – Martin L. Sep 10 '13 at 19:41

1 Answers1

0

The socket buffer is owned by the kernel, you will never be allowed to write into kernel space. Never, ever. Too much of a security risk.

The only way to do zero-copy is to use vmsplice(2), but it is not officially supported for sockets and is not recommended to use for anything other then pipes.

If you do decide to use vmsplice, keep in mind that you must then commit your data in chunks of pages sysconf(_SC_PAGESIZE). Also it is a Linux only syscall and not portable.

Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • Isn't a socket a pipe? I thought sockets were pretty much the major justification for `splice` e.g. `sendfile`. – Duck Sep 10 '13 at 15:31
  • @Duck A pipe is essentially just a fifo with a certain buffer. A socket has an underlying protocol, it's associated control stack and other socket control methods aside from being generally bi-directional. It's a far more complex structure and `splice`/`vmsplice` were not designed for use with sockets. – Sergey L. Sep 11 '13 at 09:56
  • Pipes, fifos and sockets all fall under the general term pipe. A socket may or may not have an underlying protocol, e.g. the domain sockets of OP's question, which are in effect just a kernel managed buffer with socket semantics. Splicing to and from tcp sockets has been (officially or not) supported for 4 or 5 years now since 2.6.25 – Duck Sep 11 '13 at 13:51