Visual C++ Network: When does 'send()' return?
Q: When does 'send()' return?
A: As being indicated in the FAQ "Does one call to 'send()' result in one call to 'recv()'?" , there are some specialties about the 'send()' function as well which need to be understood.
If no error has occurred, 'send()' will return the number of bytes being sent, indicating success. However, this does not mean that the data has been received by the receiving side. To make it more clear, it does not mean that the data is on the wire either. In general, a successful 'send()' simply means that the data has been passed to the lower winsock layer for processing. Since TCP guarantees delivery of data, it can be assured that the data that is handed down for processing will be delivered, as long as the connection is not abnormally terminated and there is no out-of-resource condition on the receiving side.
So, when is the data handed over for processing? The data to be sent is always buffered at an intermediate level. This buffer size is defined by the 'SO_SNDBUF' option setting, which is 8K by default. If this buffer is full or 0, the application buffer for 'send()' will be locked (so that it cannot be paged out) and the 'send()' call will be blocked as long as the buffer is locked. In case of overlapped 'send', the call will fail with the error 'WSA_IO_PENDING'. Once the buffer is locked it is fetched directly by TCP for processing. Then the blocking 'send()' call succeeds and in the case of overlapped sockets, a completion is posted.
Having said the above, one thing to remember is, that 'send()' never guarantees that all the data submitted in the buffer will be sent by TCP with one call. Hence, it is important to check the return value of 'send()' to see if all of the data submitted has been sent successfully or not. If the return value is less than the length of the buffer (passed as third argument), then 'send()' should be called again and so on until all the data has been sent. Note, that this does not apply if overlapped 'send' is being used. In this case, all the data submitted would be send, thereby allowing the user to post multiple 'send' calls. So, you do not have to worry about one of the overlapped 'send' calls completing with only partially sending the data.
Thanks to Mr. Andreas Masur for his help.