Winsock Networking API

Last Updated: October 26, 2023 | Version: Windows 11 SDK

The Windows Sockets API (Winsock) is a Microsoft Windows implementation of the Berkeley sockets API. It provides a networking interface for applications to communicate over TCP/IP and other network protocols supported by Windows.

Introduction to Winsock

Winsock enables Windows-based applications to participate in network communications. It supports both connection-oriented (like TCP) and connectionless (like UDP) communication paradigms. Developers can use Winsock to build a wide range of network applications, including:

Key Concepts

Sockets

A socket is an endpoint for communication. It's an abstract representation of a communication channel. In Winsock, sockets are represented by a handle of type SOCKET.

Address Families

Winsock supports various address families, with the most common being:

Socket Types

Winsock defines several socket types:

Protocols

Common protocols used with Winsock include:

Core Winsock Functions

Here are some of the fundamental functions you'll use when working with Winsock:

Initialization and Cleanup

Socket Creation and Management

Data Transfer

A Simple TCP Client Example

This example demonstrates the basic steps for creating a TCP client that connects to a server and sends a message.


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

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

#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 512

int main() {
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo* result = NULL, * ptr = NULL, hints;
    const char* sendbuf = "This is a test message.";
    char recvbuf[DEFAULT_BUFLEN];
    int iResult;
    int recvbuflen = DEFAULT_BUFLEN;

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

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Attempt to connect to an address until one succeeds
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
            ptr->ai_protocol);

        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }

        // Connect to server.
        iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
        }
        break; // Only testing the first address.
    }

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    // Send a request to the server
    iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
    if (iResult == SOCKET_ERROR) {
        printf("send failed with error: %d\n", iResult);
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // Receive the reply from the server
    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
    if (iResult > 0) {
        printf("Bytes received: %d\n", iResult);
        recvbuf[iResult] = '\0'; // Null-terminate the received data
        printf("Server response: %s\n", recvbuf);
    } else if (iResult == 0) {
        printf("Connection closing...\n");
    } else {
        printf("recv failed with error: %d\n", WSAGetLastError());
    }

    // Shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", iResult);
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}
        

Advanced Topics

Winsock Function Reference

For more in-depth information and detailed examples, please refer to the Winsock Tutorials and the API Reference.