Reputation: 57
This is a two-parter post. I'm writing a little piece of code to receive UDP packets, using WSARecvFrom(). I create the socket with WSA_FLAG_OVERLAPPED, I set the socket to nonblocking mode with ioctlsocket() call, bind it to a port, create an extended WSAOVERLAPPED structure instance, post my receive with a completion routine, and wait on one of the alertable wait functions. And I receive packets, works fine. Part One:
Following is from Windows Dev-Center, WSARecvFrom function documentation:
"If no error occurs and the receive operation has completed immediately, WSARecvFrom returns zero. In this case, the completion routine will have already been scheduled to be called once the calling thread is in the alertable state."
What does that mean?
My understanding of "the receive function has completed immediately" is that, the function has received something from the socket and has populated the buffer with whatever was sent to it, has updated the lpNumberOfBytesRecvd parameter, and returned 0. Why is there a need to call the completion routine in this case? What would the value of cbTransfered of the completion routine be in that case anyway?
Please note that I get the rest of the documentation: "Otherwise, a value of SOCKET ERROR is returned. The error code WSA IO PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time.". That's okay, WSARecvFrom() returns SOCKET_ERROR, WSAGetLastError() returns WSA_IO_PENDING, my completion routine is called where there's something to read, and I post another receive in the completion routine, and so on.
Part Two: Even if what's above is just a misunderstanding of the documentation on my part (being that this is not my native language), an async function returning succesfull completion makes the code unnecessarily repetitive. Or I'm way off. But if my understanding of succesfull completion is correct, then is there a way to prevent an async function returning success? Can I make a function like WSARecvFrom() return always SOCKET_ERROR (with WSA_IO_PENDING) and never 0?
Thanks for reading so far.
Upvotes: 0
Views: 251
Reputation: 596256
If there is already data ready to be read, WSARecvFrom()
immediately schedules the completion routine so it can be called when the thread is in an alertable state to indicate that data was read. The completion routine is always called, with the correct buffer size that was read. Regardless of whether WSARecvFrom()
actually fills the buffer or not, you should wait for the completion routine to be called before you process the buffer, that way you do not get your code out of sync with itself and you can centralize your buffer processing in one place instead of doing it in two places.
Upvotes: 1