0

I am using winapi function WSARecvFrom to receive UDP data on a socket, I am using overlapped IO with IOCP ports.

In the documentation its stated:

If no error occurs and the receive operation has completed immediately, WSARecvFrom returns zero.

And in the remarks:

If an overlapped operation completes immediately, WSARecvFrom returns a value of zero and the lpNumberOfBytesRecvd parameter is updated with the number of bytes received and the flag bits pointed by the lpFlags parameter are also updated. If the overlapped operation is successfully initiated and will complete later, WSARecvFrom returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags is not updated.

However if the function returns 0 the buffers are not updated with any new data, but the InternalHigh member of OVERLAPPED struct (which is the same as lpNumberOfBytesRecvd parameter, but for OVERLAPPED IO it should be NULL as per docs) is updated with a different number (which I assume is the correct number of bytes)

I have found in a forum from quite a while ago some people said when using WSARecvFrom with UDP and IOCP and it returns 0 it should just be ignored, is this really the case?

Should WSARecvFrom returning 0 for UDP with IOCP be ignored, if not, why would the documentation be so unclear?

I have also heard that IOCP is a superset of Overlapped IO and that is why im refering it to as such in this thread (im not sure if its really the case but this thread seems to confirm it)

xXTurner
  • 61
  • 9
  • result will be inside OVERLAPPED when I/O finished. what is unclear ? – RbMm Apr 27 '23 at 15:27
  • That is not the case, OVERLAPPED structure has all zeros except InternalHigh which shows the number of bytes. I actually forgot to mention it, as per docs you dont even provide lpNumberOfBytesRecvd parameter if you have OVERLAPPED structure, so im using that instead of the param – xXTurner Apr 27 '23 at 15:30
  • no. final status (if I/O not fail immediately) and number of bytes will be inside OVERLAPPED – RbMm Apr 27 '23 at 15:32
  • Wdym no, i literally see that the whole struct is zeros except InternalHigh (which is the bytes) – xXTurner Apr 27 '23 at 15:35
  • *lpNumberOfBytesRecvd is updated with a different number* - this is also can not be, because `*lpNumberOfBytesRecvd = lpOverlapped->InternalHigh;` - this is simply copy from OVERLAPPED – RbMm Apr 27 '23 at 15:37
  • `Wdym no, i literally see that the whole struct is zeros except InternalHigh (which is the bytes)` - and so that ? this mean final status is 0 (ok) and some bytes recv – RbMm Apr 27 '23 at 15:38
  • `lpNumberOfBytesRecvd is updated with a different number - this is also can not be, because *lpNumberOfBytesRecvd = lpOverlapped->InternalHigh; - this is simply copy from OVERLAPPED` - I meant that its different from a previous packet, thus indicating that it is indeed showing (probably) correct information – xXTurner Apr 27 '23 at 15:39
  • `Wdym no, i literally see that the whole struct is zeros except InternalHigh (which is the bytes) - and so that ? this mean final status is 0 (ok) and some bytes recv` - "and some bytes recv", the problem is NOTHING is received, the buffer is unchanged and the struct is zeroed except bytes: https://ibb.co/pvWkN13 – xXTurner Apr 27 '23 at 15:41
  • *different from a previous packet* - i dont understand what you mean. what is **previous**. if I/O not synchronous failed - final status and number of bytes will be inside overlapped. always. no exception and cases – RbMm Apr 27 '23 at 15:42
  • in this case some error in your code – RbMm Apr 27 '23 at 15:42
  • I feel like you cannot understand me, anyway the final point is InternalHigh shows correct amount of bytes for the packet received, the problem is the actual data of the packet is not accessible – xXTurner Apr 27 '23 at 15:43
  • again - or some error in your code or you wrong check buffers, wrong use buffers. your code not visible. or I/O just fail or final status will be in overlapped. in what question ? i perfect know topic – RbMm Apr 27 '23 at 15:44
  • Okay, so in theory if WSARecvFrom returns 0 I should expect to see my data in the WSABUF buffer(s) ? – xXTurner Apr 27 '23 at 15:45
  • yes, if 0 returned - I/O is finished. and data will be in buffers – RbMm Apr 27 '23 at 15:47

1 Answers1

0

WSA api behavior not depend from - are socket bind to IOCP or not. it depend from asynchronous (frequently it called Overlapped) I/O used or not.

I have also heard that IOCP is a superset of Overlapped IO and that is why im refering it to as such in this thread (im not sure if its really the case but this thread seems to confirm it)

this is absolute nonsense. IOCP and Overlapped(asynchronous) I/O different things. IOCP (xor APC and Event) is means to receive a notification when I/O is complete.

Should WSARecvFrom returning 0 for UDP with IOCP be ignored

of course no. must not be ignored any return code.

why would the documentation be so unclear?

unclear what you mean.

However if the function returns 0 the buffers are not updated with any new data, but the InternalHigh member of OVERLAPPED struct is updated with a different number (which I assume is the correct number of bytes)

this is not true. when I/O is completed without error - buffers is updated. if you think it not updated - possible you bad check, pass wrong pointers to api, or may be you send data which already in buffers - say you send 0 bytes and 0 already in buffers. wihout view concrete code - impossible say.

the general rule for overlapped I/O:

  1. api return ERROR_IO_PENDING - I/O yet not completed. when it will be completed - some notification will be - event set or APC or packet pushed to IOCP. when you got this notification - I/O already completed. this final status will be in OVERLAPPED. it can be 0 or some error
  2. api return another error - this mean I/O is finished with this error. no data is received or sent. overlapped will be not updated in this case.
  3. api return 0 (noerror). I/O is finished. OVERLAPPED updated with actual bytes count received or send. buffers (if this recv) already updated with received data
RbMm
  • 31,280
  • 3
  • 35
  • 56