Winsock UDP Communication

Overview

This tutorial demonstrates how to create a simple UDP client and server using the Windows Sockets (Winsock) API. UDP is a connection‑less protocol that provides low‑latency communication without guaranteeing delivery.

Prerequisites

UDP Client

The client sends a message to a server using sendto.

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

#pragma comment(lib, "Ws2_32.lib")

int main() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);

    SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock == INVALID_SOCKET) {
        std::cerr << "Socket creation failed\n";
        return 1;
    }

    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(5150);
    inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);

    const char* msg = "Hello from UDP client!";
    int sendResult = sendto(sock, msg, (int)strlen(msg), 0,
                            reinterpret_cast<SOCKADDR*>(&serverAddr),
                            sizeof(serverAddr));
    if (sendResult == SOCKET_ERROR) {
        std::cerr << "sendto failed: " << WSAGetLastError() << "\n";
    } else {
        std::cout << "Message sent.\n";
    }

    closesocket(sock);
    WSACleanup();
    return 0;
}

UDP Server

The server receives messages using recvfrom and prints them.

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

#pragma comment(lib, "Ws2_32.lib")

int main() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);

    SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock == INVALID_SOCKET) {
        std::cerr << "Socket creation failed\n";
        return 1;
    }

    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(5150);
    serverAddr.sin_addr.s_addr = INADDR_ANY;

    if (bind(sock, reinterpret_cast<SOCKADDR*>(&serverAddr), sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Bind failed: " << WSAGetLastError() << "\n";
        return 1;
    }

    char buffer[512];
    sockaddr_in clientAddr{};
    int clientAddrSize = sizeof(clientAddr);
    int recvLen = recvfrom(sock, buffer, sizeof(buffer) - 1, 0,
                           reinterpret_cast<SOCKADDR*>(&clientAddr), &clientAddrSize);
    if (recvLen == SOCKET_ERROR) {
        std::cerr << "recvfrom failed: " << WSAGetLastError() << "\n";
    } else {
        buffer[recvLen] = '\0';
        char clientIP[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);
        std::cout << "Received from " << clientIP << ":" << ntohs(clientAddr.sin_port)
                  << " - " << buffer << "\n";
    }

    closesocket(sock);
    WSACleanup();
    return 0;
}

Testing the Example

  1. Open two Visual Studio command prompts.
  2. Compile the server:
    cl /EHsc server.cpp ws2_32.lib
  3. Compile the client:
    cl /EHsc client.cpp ws2_32.lib
  4. Run server.exe first, then client.exe.
  5. Observe the server output displaying the received message.

References