As you can see at this question, which covers other socket options, the answer depends on operating system, so both answers may be correct, as one is an answer from the Linux world and one is an answer from the UNIX (BSD and Co) world.
In BSD and BSD clones, this option means the following:
If the socket is non-blocking and you call send()
, it must be able to either accept all supplied data at once or accept at least SO_SNDLOWAT
bytes of data; if that is not possible, it will not accept any data and send()
fails with error.
So if you set SO_SNDLOWAT
to 100 and try to send 50 bytes, it will send 50 bytes or nothing. If you set SO_SNDLOWAT
to 100 and try to send 200 bytes, it must at least accept 100 bytes of data, it can accept more, up to the entire 200 bytes, as well as any value between 100 and 200, just not less than 100. Keep in mind, the default value of SO_SNDLOWAT
is 1 and that's also the default behavior of a non-blocking socket (it must accept at least 1 byte or fail with EWOULDBLOCK
)
Note that UDP sockets are always all-or-nothing, they never accept only "part of the data", thus setting SO_SNDLOWAT
is only relevant for TCP sockets, that may accept only a part of the data offered.
If the socket is blocking, setting SO_SNDLOWAT
has no real effect on the send()
call, as in that case the socket will always accept all data or it will block and then it will block until all data have been accepted or the send timeout is hit (if a send timeout has been set with SO_SNDTIMEO
or the underlying protocol has an own timeout for sending).
Regardless if the socket is blocking or not, regardless if it is UDP or TCP, a poll()
or select()
call will only claim that this socket is writable, if at least SO_SNDLOWAT
bytes can be accepted by a send()
call.
So what is this option really good for? Usually it is used to avoid that your process feeds data in byte-for-byte once the socket buffer ran full but in larger chunks as with default behavior, select()
and poll()
will say the socket is writable, even if there's just room for a single byte in the socket buffer. In other words, it's just a performance optimization, as code that works correctly with arbitrary socket writes will work correctly regardless if SO_SNDLOWAT
is set and regardless to which value, it may just need a lot less CPU time in some extreme situations if SO_SNDLOWAT
has a reasonable value. But as with all performance tweaks, if you don't know exactly what you are doing, you may easily make things much worse by setting the wrong values, so if in doubt, don't touch that setting.