Winsock Initialization

This section covers the essential steps and functions required to initialize and use the Windows Sockets API (Winsock) in your applications. Proper initialization ensures that the Winsock DLL is loaded and ready to handle network communication.

Core Concepts

Before making any Winsock calls, you must initialize the Winsock environment. This typically involves calling the WSAStartup function. This function loads the Winsock DLL and makes it available for use. It also performs version negotiation to ensure compatibility between your application and the Winsock implementation.

WSAStartup

Initializes the Winsock DLL. This function must be called successfully before any other Winsock functions can be used. For each successful call to WSAStartup, there must be a corresponding call to WSACleanup.

Syntax

int WSAStartup(
  [in]  WORD                 wVersionRequired,
  [out] LPWSADATA            lpWSAData
);

Parameters

Name Type Description
wVersionRequired WORD The Winsock version requested by the application. The high byte is the minor version number, and the low byte is the major version number. For Winsock 2.2, this value should be MAKEWORD(2, 2).
lpWSAData LPWSADATA A pointer to a WSADATA structure that receives information about the Winsock implementation.

Return Value

On success, WSAStartup returns 0. On failure, it returns an appropriate Winsock error code.

Remarks

An application must call WSAStartup before it can use any functions in the Winsock API. An application can call WSAStartup multiple times without issue, as long as each WSAStartup call is matched by a WSACleanup call. This allows a Winsock DLL to be shared by multiple applications or DLLs.

The wVersionRequired parameter specifies the Winsock version that the application is written for. The Winsock DLL must be able to support this version. If the Winsock DLL supports the requested version, the lpWSAData->wVersion member will contain the actual version supported by the DLL.

Example Usage

#include <winsock2.h>
#include <stdio.h>

// Link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int main() {
    WSADATA wsaData;
    int iResult;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    printf("Winsock initialized successfully. Version: %d.%d\n",
           LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

    // ... proceed with Winsock operations ...

    // Clean up Winsock
    WSACleanup();
    return 0;
}

WSACleanup

Removes a reference to the Winsock DLL from the application or DLL that called WSAStartup. When the last application or DLL calls WSACleanup, WSACleanup unloads the Winsock DLL. Applications must call WSACleanup for every successful call to WSAStartup.

Syntax

int WSACleanup();

Parameters

None.

Return Value

WSACleanup always returns 0.

Remarks

It is essential to call WSACleanup when your application or DLL finishes using Winsock. Failing to do so can lead to resource leaks and incorrect behavior.

Common Versioning

Error Handling

If WSAStartup returns a non-zero value, an error has occurred. The return value is a specific Winsock error code. You can use the WSAGetLastError function to retrieve more detailed error information after a Winsock function fails. However, WSAGetLastError should not be called after WSAStartup fails; the return value of WSAStartup itself indicates the error.