1
votes

I am trying to solve the problem of being able to read from one socket and then write to another socket without blocking and without buffering for cases where I cannot use splice().

As a first pass solution what I have in mind is to query the remaining size of the send buffer on the write socket, read that much from the reading socket, then write that much to the write socket knowing we can't block.

I have found someone claim at https://stackoverflow.com/a/9982492/4598583 that to query the remaining buffer size you can do the following:

getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &send_buf, &optlen);

However, I cannot find a reference to whether SO_SNDBUF will return the maximum buffer size or the remaining buffer size.

Can anyone confirm if querying the remaining (not maximum) buffer size is possible?

Alternatively, when a write socket indicates that that socket is writable (via poll() or some other mechanism) is there a minimum size of data defined anywhere that you can write without blocking or truncation in this case?

1
If you don't want to block, setting the sockets to non-blocking mode is the best way to guarantee that you won't. As for buffering, you're buffering anyway since you have to read the bytes into a buffer before writing them out to the other socket; so keeping some of those bytes in the buffer until the next time the output-socket selects as ready-for-write isn't that much different. - Jeremy Friesner

1 Answers

1
votes

SO_SNDBUF don't give you the remaining size of send buffer, but the maximum size of it. This should be the max buffer that the OS can send each time, or max send witout blocking. So it should fit anyway your need.
From Linux Manual:

SO_SNDBUF Sets or gets the maximum socket send buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/wmem_default file and the maximum allowed value is set by the /proc/sys/net/core/wmem_max file. The minimum (doubled) value for this option is 2048.