Microsoft Docs

Advanced Winsock Functions

The Winsock 2 API provides several advanced functions that enable asynchronous I/O, event-driven programming, and fine‑grained control over socket behavior.

WSAAsyncSelect

Associates a socket with a window handle and notifies the application of network events via WM_SOCKET messages.

int WSAAsyncSelect(
    SOCKET s,
    HWND hWnd,
    unsigned int wMsg,
    long lEvent);

Typical usage:

#include <winsock2.h>
#include <windows.h>

void InitAsyncSocket(SOCKET s, HWND hWnd) {
    WSAAsyncSelect(s, hWnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE);
}

WSAEventSelect

Registers a socket to signal an event object when network events occur.

int WSAEventSelect(
    SOCKET s,
    WSAEVENT hEventObject,
    long lNetworkEvents);

Example with a manual‑reset event:

WSAEVENT event = WSACreateEvent();
WSAEventSelect(s, event, FD_READ | FD_CLOSE);
WaitForSingleObject(event, INFINITE);

WSAWaitForMultipleEvents

Waits for any of several event objects to become signaled.

DWORD WSAWaitForMultipleEvents(
    DWORD cEvents,
    const WSAEVENT *lphEvents,
    BOOL fWaitAll,
    DWORD dwTimeout,
    BOOL fAlertable);

Sample usage:

WSAEVENT events[2] = { event1, event2 };
DWORD index = WSAWaitForMultipleEvents(2, events, FALSE, 5000, FALSE);
if (index == WSA_WAIT_EVENT_0) { /* event1 signaled */ }
else if (index == WSA_WAIT_EVENT_0 + 1) { /* event2 signaled */ }

WSAIoctl

Controls the mode of a socket, e.g., enabling non‑blocking I/O or retrieving the amount of data pending.

int WSAIoctl(
    SOCKET s,
    DWORD dwIoControlCode,
    LPVOID lpvInBuffer,
    DWORD cbInBuffer,
    LPVOID lpvOutBuffer,
    DWORD cbOutBuffer,
    LPDWORD lpcbBytesReturned,
    LPWSAOVERLAPPED lpOverlapped,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);

To enable non‑blocking mode:

u_long mode = 1; // 1 = non‑blocking
ioctlsocket(s, FIONBIO, &mode); // equivalent to WSAIoctl with FIONBIO

Performance Tuning

  • Use WSASetSocketSecurity for secure transports when possible.
  • Prefer WSASendMsg over multiple WSASend calls to reduce system calls.
  • Batch read/write operations using WSARecvMsg and WSASendMsg.
  • Leverage SO_CONDITIONAL_ACCEPT to defer accept processing until data is available.

Error Handling

All Winsock functions return SOCKET_ERROR on failure. Use WSAGetLastError() to retrieve the error code.

int result = WSAAsyncSelect(s, hWnd, WM_SOCKET, FD_READ);
if (result == SOCKET_ERROR) {
    int err = WSAGetLastError();
    // Handle or log the error
}