The Linux Programming Interface

(nextflipdebug5) #1

1262 Chapter 61


The count argument specifies the number of bytes to be transferred. If end-of-
file is encountered before count bytes are transferred, only the available bytes are
transferred. On success, sendfile() returns the number of bytes actually transferred.
SUSv3 doesn’t specify sendfile(). Versions of sendfile() are available on some
other UNIX implementations, but the argument list is typically different from the
version on Linux.

Starting with kernel 2.6.17, Linux provides three new (nonstandard) system
calls—splice(), vmsplice(), and tee()—that provide a superset of the functionality
of sendfile(). See the manual pages for details.

The TCP_CORK socket option
To further improve the efficiency of TCP applications using sendfile(), it is some-
times useful to employ the Linux-specific TCP_CORK socket option. As an example,
consider a web server delivering a page in response to a request by a web browser.
The web server’s response consists of two parts: HTTP headers, perhaps output
using write(), followed by the page data, perhaps output using sendfile(). In this sce-
nario, normally two TCP segments are transmitted: the headers are sent in the first
(rather small) segment, and then the page data is sent in a second segment. This is
an inefficient use of network bandwidth. It probably also creates unnecessary work
for both the sending and the receiving TCP, since in many cases the HTTP headers
and the page data would be small enough to fit inside a single TCP segment. The
TCP_CORK option is designed to address this inefficiency.
When the TCP_CORK option is enabled on a TCP socket, all subsequent output is
buffered into a single TCP segment until either the upper limit on the size of a seg-
ment is reached, the TCP_CORK option is disabled, the socket is closed, or a maximum
of 200 milliseconds passes from the time that the first corked byte is written. (The
timeout ensures that the corked data is transmitted if the application forgets to dis-
able the TCP_CORK option.)
We enable and disable the TCP_CORK option using the setsockopt() system call
(Section 61.9). The following code (which omits error checking) demonstrates the
use of TCP_CORK for our hypothetical HTTP server example:

int optval;

/* Enable TCP_CORK option on 'sockfd' - subsequent TCP output is corked
until this option is disabled. */

optval = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, sizeof(optval));

write(sockfd, ...); /* Write HTTP headers */
sendfile(sockfd, ...); /* Send page data */

/* Disable TCP_CORK option on 'sockfd' - corked output is now transmitted
in a single TCP segment. */

optval = 0
setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, sizeof(optval));
Free download pdf