TCP data is buffered at both sender and receiver. The size of the receiver‘s socket receive buffer determines how much data can be in flight without acknowledgement, and the size of the sender‘s send buffer determines how much data can be sent before the sender blocks or gets EAGAIN/EWOULDBLOCK, depending on blocking/non-blocking mode. You can set these socket buffers as large as you like up to 2^32-1 bytes, but if you set the client receive buffer higher than 2^16-1 you must do so before connecting the socket, so that TCP window scaling can be negotiated in the connect handshake, so that the upper 16 bits can come into play. [The server receive buffer isn‘t relevant here, but if you set it >= 64k you need to set it on the listening socket, from where it will be inherited by accepted sockets, again so the handshake can negotiate window scaling.]
However I agree entirely with Martin James that this is a silly requirement. It wastes a thread, a thread stack, a socket, a large socket send buffer, an FD, and all the other associated resources at the server for two hours, and possibly affects other threads and therefore other clients. It also falsely gives the server the impression that two hours‘ worth of data has been received, when it has really only been transmitted to the receive buffer, which may lead to unknown complications in recovery situations: for example, the server may be unable to reconstruct the data sent so far ahead. You would better off not connecting until you are ready to start receiving the data, or else reading and spooling the data to yourself at the client for processing later.
If you want see your buffer size in terminal, you can take a look at:
/proc/sys/net/ipv4/tcp_rmem
(for read)/proc/sys/net/ipv4/tcp_wmem
(for write)
They contain three numbers, which are minimum, default and maximum memory size values (in byte), respectively.
For getting the buffer size in c/c++ program the following is the flow
int n; unsigned int m = sizeof(n); int fdsocket; fdsocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); // example getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m); // now the variable n will have the socket size
You can increase the value from the default, but you can‘t increase it beyond the maximum value. Use setsockopt
to change the SO_RCVBUF
option:
int n = 1024 * 1024; if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1) { // deal with failure, or ignore if you can live with the default size }
Note that this is the portable solution; it should work on any POSIX platform for increasing the receive buffer size. Linux has had autotuning for a while now (since 2.6.7, and with reasonable maximum buffer sizes since 2.6.17), which automatically adjusts the receive buffer size based on load. On kernels with autotuning, it is recommended that you not set the receive buffer size using setsockopt
, as that will disable the kernel‘s autotuning. Using setsockopt
to adjust the buffer size may still be necessary on other platforms, however.