Hacker News new | ask | show | jobs
by purplefox 5157 days ago
That's right. If you use the sendFile() method and you're on an OS that supports it, then the kernel will do the copying directly from file to socket for you.

You can also serve files in the more conventional "node.js-style" way (i.e. pump the buffers manually from file to socket) if you like. It's just slower than getting the kernel to do the work for you.

1 comments

But you have to dedicate a thread to sendFile() (by nature).
Not really, typically you'd have one thread handling all sendFiles through a single selector over the destination sockets. As a matter of fact, it's actually really painful to do sendFile in Java from a single thread, because when the channel isn't ready for sending, rather than returning EAGAIN and letting you busy-loop or wait/retry or whatever, it throws an exception. So you have to use a selector to do sendfile, and in that case, why not use multiple tasks with the same selector?
(Response to jbooth, but for some reason I can't reply to that directly.)

The whole point of sendfile is to make one system call to send all the data in one stream to another, which in general may block. If you're polling and sending only small chunks at a time (whatever you can write without blocking), is it really that much of an advantage over read/write on the same poll? (If you're not doing that, then you have to block, and you have to dedicate a thread to it.)

If the socket you're writing to has been set to nonblocking, then sendfile exhibits the behavior I described, sending EAGAIN sometimes (check man sendfile). This means typically you want to put a selector in front of it and poll the selector, then send to any sockets that are writable, loop back and poll again.

It's still an advantage over read/write because you're getting the 0-copy behavior.