0

I am not sure how to initialize WSAOVERLAPPED when using IOCP. I don't think that I need to initialize it at all, I only set WSAOVERLAPPED.hEvent to NULL (not sure if this is necessary either). Is this code correct:

// Send data
char buffer[1024];

WSABUF wsaBuf;
wsaBuf.buf = buffer;
wsaBuf.len = 1024;

WSAOVERLAPPED wsaOverlapped;
wsaOverlapped.hEvent = NULL;

WSASend(s, &wsaBuf, 1, NULL, 0, &wsaOverlapped, NULL);

Also, is initializing OVERLAPPED when using WSARecv() the same as initializing WSAOVERLAPPED?

  • The code you show is broken. The data buffer and the `OVERLAPPED` must both be valid until the overlapped send completes and the completion is extracted from the IOCP. ONLY the WSABUF can be stack based and exist purely for the duration of the `WSASend()` API call. – Len Holgate Mar 05 '15 at 22:17
  • @Len Holgate So `buffer` and `wsaOverlapped` should be created on the heap? –  Mar 06 '15 at 14:43
  • Yes. Ideally with some kind of pooling allocator that allows you to reuse them rather than directly on the heap. – Len Holgate Mar 06 '15 at 15:52

2 Answers2

0

The WSAOVERLAPPED structure is subject to the same rules as the OVERLAPPED structure, i.e.,

Any unused members of this structure should always be initialized to zero before the structure is used in a function call. Otherwise, the function may fail and return ERROR_INVALID_PARAMETER.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • But should I initialize any member of `WSAOVERLAPPED` or `OVERLAPPED` before passing them to `WSASend()` or `WSARecv()`? –  Mar 05 '15 at 00:35
  • Of course. If you're using them, you have to initialize them to the appropriate value, e.g., by setting hEvent to a valid event handle; if you're not using them, you have to initialize them to zero. – Harry Johnston Mar 05 '15 at 00:43
  • If I do not want to use events, and only want to be notified through completion packets, should I set `WSAOVERLAPPED.hEvent` to `NULL`, or is it okay not to initialize it at all? Also, what about the other members, are they used by me or by the system? –  Mar 05 '15 at 01:19
  • @user4592590: If you actually read the [`WSAOVERLAPPED`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms741665.aspx), [`WSASend()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms742203.aspx), and [`WSARecv()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms741688.aspx) documentation, they answer the `hEvent` question. In a nutshell, if you perform an overlapped send/read without IOCP, `hEvent` must be a valid event object or NULL. Otherwise, with IOCP, you set `hEvent` to whatever you want, it is passed as-is to the IOCP handler as user-defined data. – Remy Lebeau Mar 05 '15 at 02:46
  • 1
    @Remy Lebeau I am using IOCP, but at the same time I have assigned `WSAOVERLAPPED.hEvent` to a valid event instance, and waited on it. What happened is that I was able to wait successfully until `WSASend()` has completed, and so how can it be a user defined data? I mean wouldn't the system see `WSAOVERLAPPED.hEvent` is not `NULL`, and so treat it as a valid event instance? –  Mar 05 '15 at 03:25
  • 1
    @user4592590: Apparently the meaning of `hEvent` depends on the value of the `lpCompletionRoutine` parameter of `WSASend()`/`WSARecv()`, not on whether the socket is associated with an IOCP or not. If you set `lpCompletionRoutine` to NULL, you must set `hEvent` to a valid event object or NULL. If not NULL, the event will be signaled when the I/O is finished, and the IOCP will also receive a completion packet. – Remy Lebeau Mar 05 '15 at 04:17
  • In the specific case of WSASend and WSARecv, `hEvent` is the only part of the structure that you might want to set to anything other than zero. – Harry Johnston Mar 05 '15 at 05:12
0
   memset(&wsaOverlapped, 0, sizeof(wsaOverlapped));

Or explicitly set all values to zero.

Len Holgate
  • 21,282
  • 4
  • 45
  • 92