Winsock2: Upon partial transmission, does nonblocking send() retry until success or abandon?

I'm using send() with nonblocking sockets and wanted to know how to interpret its return value. According to [1], the return value is the number of bytes already transmitted, which may be less than the number requested to be transmitted. The return value can also be SOCKET_ERROR (-1) with WSAEWOULDBLOCK error code if the peer's receive buffer is full [2].

If send's return value is less than what was requested (say 3000 out of 10000 bytes), after send returns, does it continue to try sending 7000 bytes in the background such that after some time all 10000 bytes are sent? Or is it the responsibility of the programmer to call send() at a later time to try sending the other 7000 bytes?

[1] MSDN: send
https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send

[2] SO: WSAGetLastError() never return WSAEWOULDBLOCK when nonblock send return -1,why?
https://stackoverflow.com/a/32444753/5972766
Last edited on
send() or write() will transmit up to N bytes, and it returns the number of bytes that have actually been transmitted (i.e., copied into the NIC's outbound buffer). If a single call has transmitted fewer than N bytes, e.g., because less then N bytes of "free" space were currently available in the NIC's outbound buffer, then that is not considered an error. It is expected. And it is the job of the user to call send() or write() in a loop until everything has been sent. You will have to keep track of how many bytes have already been sent and calculate the proper offset (from the start of your messages) when you do the next send() or write() call.

The only difference between "blocking" and "non-blocking" mode is when zero bytes can be transmitted at the moment, i.e., when the NIC's outbound buffer is completely full. In "blocking" mode, send() or write() will simply block until at least one byte can be transmitted; it does not wait until all bytes can be transmitted, though. Conversely, in "non-blocking" mode, the send() or write() will fail immediately (with EAGAIN or EWOULDBLOCK error), if nothing at all can be sent at the very moment; it never waits.

To make a long storry short, if a single send() or write() invocation did not transmit all bytes, which can always happen, then the "remaining" bytes will not be transmitted automatically (in the background). You'll have to send those remaining bytes explicitly.

In "non-blocking" mode this probably means that, if not all data could be sent at once, you will call poll() to wait until the socket becomes "ready for writing" again before you actually try to send the rest – since "busy waiting" (retrying immediately) would be wasteful.
Last edited on
If the return value is not SOCKET_ERROR, then only the returned number of bytes have been sent. It is the senders responsibility to re-send any non-sent bytes. Note that this return of less than requested may happen multiple times so the send() should be in a loop which terminates either on SOCKET_ERROR or return value equal what was requested.
Registered users can post here. Sign in or register to post.