Search code examples
c++winapiudpwinsockwsaasyncselect

Does connect() ever fail with WSAEWOULDBLOCK for UDP (SOCK_DGRAM) sockets?


When using Winsock with TCP connections (SOCK_STREAM, connection-oriented), calling WSAAsyncSelect puts the socket into non-blocking mode. A call to connect at that point will generally return with SOCKET_ERROR and a WSAGetSelectError() return of WSAEWOULDBLOCK, indicating that the connection is happening in the background and to wait for receipt of a FD_CONNECT message indicating the actual success / failure of the connection attempt.

if (WSAAsyncSelect(sock_remote, hDlg, WM_SOCKET_REMOTE_TCP, FD_CLOSE | FD_CONNECT | FD_WRITE | FD_READ) == SOCKET_ERROR) {
    // report error message here...
    closesocket(sock_remote);
} else if (connect(sock_remote, (const sockaddr*)(&addr), sizeof(addr)) == SOCKET_ERROR &&
    WSAGetLastError() != WSAEWOULDBLOCK) {
    // this always returns SOCKET_ERROR but we care about whether it's WSAEWOULDBLOCK or something else
    // report error message here...
    closesocket(sock_remote);
} else { ... }

// elsewhere

    switch (WSAGETSELECTEVENT(lParam))
    {
    case FD_CONNECT:
        // Handle connection success / failure

However, with UDP (connectionless) sockets, you can call connect() as well - it does not set up a virtual circuit, but instead does only this (Microsoft documentation for connect()):

For a connectionless socket (for example, type SOCK_DGRAM), the operation performed by connect is merely to establish a default destination address that can be used on subsequent send/ WSASend and recv/ WSARecv calls.

And indeed, in my testing, calls to connect() never fail with WSAEWOULDBLOCK - this works without needing special handling to check the error:

if (connect(remote, (const sockaddr*)(&addr), sizeof(addr)) == SOCKET_ERROR) {
    // never returns WSAEWOULDBLOCK...?  some other error occurred...
    closesocket(remote);
}

But, I am unsure if this is a "it doesn't happen on my machine" vs a "it never happens by design" situation. So my question is, "does connect() on a UDP (datagram, connectionless, non-stream-oriented, etc) socket ever fail with WSAEWOULDBLOCK?" I might assume "no" except that in the Winsock documentation for WSAAsyncSelect it says:

  • FD_CONNECT:
    1. ...
    2. After connect called, when connection is established, even when connect succeeds immediately, as is typical with a datagram socket.

As is typical, not as is guaranteed...


Solution

  • does connect() on a UDP (datagram, connectionless, non-stream-oriented, etc) socket ever fail with WSAEWOULDBLOCK?

    No.

    I might assume "no" except that in the Winsock documentation for WSAAsyncSelect it says:

    • FD_CONNECT:
      1. ...
      2. After connect called, when connection is established, even when connect succeeds immediately, as is typical with a datagram socket.

    That documentation is wrong, or at least misleading. You will not receive an FD_CONNECT notification for a UDP socket.