Chapter 8. Sockets
8.1. Socket Options
TCP_NODELAY
and TCP_CORK
.
TCP_NODELAY
TCP is the most common transport protocol, which means it is often used to solve many different needs. As new application and hardware features are developed, and kernel architecture optimizations are made, TCP has had to introduce new heuristics to handle the changes effectively.
TCP_NODELAY
is a socket option that can be used to turn this behavior off. It can be enabled through the setsockopt
sockets API, with the following function:
int one = 1; setsockopt(descriptor, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
TCP_NODELAY
can also interact with other optimization heuristics to result in poor overall performance.
TCP_NODELAY
enabled.
writev
on a socket with TCP_NODELAY
enabled.
TCP_CORK
Another TCP socket option that works in a similar way is TCP_CORK
. When enabled, TCP will delay all packets until the application removes the cork, and allows the stored packets to be sent. This allows applications to build a packet in kernel space, which is useful when different libraries are being used to provide layer abstractions.
TCP_CORK
option can can be enabled by using the following function:
int one = 1; setsockopt(descriptor, SOL_TCP, TCP_CORK, &one, sizeof(one));
TCP_CORK
is often referred to as corking the socket
.
int zero = 0; setsockopt(descriptor, SOL_TCP, TCP_CORK, &zero, sizeof(zero));Once the socket is uncorked, TCP will send the accumulated logical package immediately, without waiting for further packets from the application.
Example 8.1. Using TCP_NODELAY
and TCP_CORK
TCP_NODELAY
and TCP_CORK
can have on an application.
~]$ ./tcp_nodelay_server 5001 10000
no_delay
option to enable TCP_NODELAY
socket options. Use the cork
option to enable TCP_CORK
. In all cases it will send 15 packets, each of two bytes, and wait for a response from the server.
TCP_NODELAY
nor TCP_CORK
are in use. This is a baseline measurement. TCP coalesces writes and has to wait to check if the application has more data than can optimally fit in the network packet:
~]$ ./tcp_nodelay_client localhost 5001 10000
10000 packets of 30 bytes sent in 400129.781250 ms: 0.749757 bytes/ms
TCP_NODELAY
only. TCP is instructed not to coalesce small packets, but to send buffers immediately. This improves performance significantly, but creates a large number of network packets for each logical packet:
~]$ ./tcp_nodelay_client localhost 5001 10000 no_delay
10000 packets of 30 bytes sent in 1649.771240 ms: 181.843399 bytes/ms using TCP_NODELAY
TCP_CORK
only. It halves the time required to the send the same number of logical packets. This is because TCP coalesces full logical packets in its buffers, and sends fewer overall network packets:
~]$ ./tcp_nodelay_client localhost 5001 10000 cork
10000 packets of 30 bytes sent in 850.796448 ms: 352.610779 bytes/ms using TCP_CORK
TCP_CORK
is the best technique to use. It allows the application to precisely convey the information that a packet is finished and must be sent without delay. When developing programs, if they need to send bulk data from a file, consider using TCP_CORK
with sendfile
.
Note
- sendfile(2)
- “TCP nagle sample applications”, which are example applications of both socket options, written in C. To download them, right-click and save from the following links: