Socket Programming (Winsock)

This section details the Windows Sockets API (Winsock), a programming interface that provides applications with access to the Windows network protocol stack. Winsock enables the development of network-aware applications that can communicate across various network protocols, including TCP/IP, UDP, and others.

Overview of Sockets

A socket is an endpoint for communication. It's a combination of an IP address and a port number. Applications use sockets to send and receive data over a network. The Winsock API provides a set of functions and structures that abstract the underlying network protocols, allowing developers to write network code without needing to manage low-level protocol details.

Key Concepts

  • Address Families: Specifies the protocol family (e.g., AF_INET for IPv4, AF_INET6 for IPv6).
  • Socket Types: Defines the communication semantics (e.g., SOCK_STREAM for connection-oriented, SOCK_DGRAM for connectionless).
  • Protocols: The specific protocol to use within an address family and socket type (e.g., IPPROTO_TCP, IPPROTO_UDP).
  • Socket Descriptors: An integer handle representing an open socket.
  • Ports: A number used to identify a specific process or service on a host.

Core Winsock Functions

The Winsock API provides a rich set of functions for socket programming. Here are some of the most fundamental ones:

Initializing and Terminating Winsock

  • WSAStartup(): Initializes the Winsock DLL and specifies the version of Winsock to be used. This function must be called before any other Winsock function.
  • WSACleanup(): Terminates the use of the Winsock DLL. It decrements a reference count and, when the count reaches zero, unloads the DLL.

Creating and Managing Sockets

  • socket(): Creates a socket that is bound to a specific transport service provider.
  • bind(): Associates a local address (IP address and port number) with a socket.
  • listen(): Puts a socket into a state where it listens for incoming connection requests.
  • accept(): Accepts a connection request on a socket that is listening for connections.
  • connect(): Establishes a connection to a remote socket.
  • closesocket(): Closes an existing socket.

Sending and Receiving Data

  • send() / sendto(): Sends data on a connected socket or to a specific address.
  • recv() / recvfrom(): Receives data from a connected socket or from a specific address.

Getting Socket Information

  • getsockname(): Retrieves the local address associated with a socket.
  • getpeername(): Retrieves the address of the remote endpoint of a socket.
  • gethostbyname(): Retrieves host name resolution information from a DNS server.

Example: A Simple TCP Client

Here's a basic C++ example demonstrating how to create a TCP client socket and connect to a server:


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

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

int main() {
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        std::cerr << "WSAStartup failed: " << iResult << std::endl;
        return 1;
    }

    SOCKET ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        std::cerr << "socket creation failed: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    sockaddr_in clientService;
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr("127.0.0.1"); // Target IP
    clientService.sin_port = htons(27015);              // Target Port

    if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR) {
        std::cerr << "Connect failed: " << WSAGetLastError() << std::endl;
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Connected to server." << std::endl;

    // ... send/receive data ...

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

Tip

Always initialize Winsock using WSAStartup before making any other Winsock calls and terminate it with WSACleanup when your application is finished with networking.

Further Reading