There are two normal scenarios for both WSASend() and
WSARecv() functions:
-
when the function returns 0, it means that I/O operation was completed
immediately -
when the function return SOCKET_ERROR value and WSAGetLastError() returns
WSA_IO_PENDING, that means I/O operation was scheduled successfully and it
will be completed later.
In other words it means, that even when you plan to manage socket I/O
operations asynchronously, you still need to handle the case, that some
operations can be competed synchronously.
If you use I/O Completion Port, there is an easy trick so that immediately
completed operations can be reported as they are completed naturally in
asynchronous order.
iResult = WSARecv(CustomOverlapped.some_socket,
&CustomOverlapped.wsaBuffer, 1,
&CustomOverlapped.dwBytes,
&CustomOverlapped.dwFlags,
&CustomOverlapped.overlapped, NULL);
if (((SOCKET_ERROR == iResult) && (WSA_IO_PENDING != WSAGetLastError())){
//something went wrong
//handle the error here
}
//test if operation is already completed
if (0==iResult){
//submit I/O completion packet to IOCP
PostQueuedCompletionStatus(hIOCP, sizeof(CustomOverlapped), 0, &CustomOverlapped.overlapped);
}
This will allow to postpone the handling of the operation results and also
to keep things logically clear in the source code.