UDP Socket API
This document provides an in-depth look at the User Datagram Protocol (UDP) socket API in Windows. UDP is a connectionless protocol that offers speed and efficiency for applications where reliability is not paramount.
Introduction to UDP
UDP (User Datagram Protocol) is a transport layer protocol that provides a connectionless, unreliable datagram service. Unlike TCP, UDP does not establish a connection before sending data, nor does it guarantee delivery, order, or duplicate protection. This makes it ideal for real-time applications such as streaming media, online gaming, and DNS queries, where low latency is critical.
Key characteristics of UDP include:
- Connectionless: No handshake is required to send data.
- Unreliable: Packets may be lost, duplicated, or arrive out of order.
- Datagram-Oriented: Data is sent in discrete packets (datagrams).
- Low Overhead: Minimal header information, leading to faster transmission.
Core UDP Socket Functions
The Windows Sockets API (Winsock) provides functions to create, configure, send, and receive UDP datagrams. The fundamental socket type for UDP is SOCK_DGRAM.
Creating a UDP Socket
A UDP socket is created using the socket() function:
SOCKET udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (udpSocket == INVALID_SOCKET) {
// Handle error
WSAGetLastError();
}
AF_INET: Specifies the IPv4 address family.SOCK_DGRAM: Indicates a datagram socket.IPPROTO_UDP: Specifies the UDP protocol.
Binding a Socket
For a server application or a client that needs to receive data, the socket must be bound to a specific local IP address and port using bind():
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345); // Example port
serverAddr.sin_addr.s_addr = INADDR_ANY; // Bind to any available interface
if (bind(udpSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
// Handle error
WSAGetLastError();
}
Using INADDR_ANY allows the application to receive datagrams destined for any IP address configured on the host.
Sending UDP Datagrams
Data is sent using sendto(), which requires specifying the destination address and port for each datagram:
struct sockaddr_in clientAddr;
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(6789); // Destination port
clientAddr.sin_addr.s_addr = inet_addr("192.168.1.100"); // Destination IP
const char* message = "Hello, UDP!";
int bytesSent = sendto(udpSocket, message, strlen(message), 0, (SOCKADDR*)&clientAddr, sizeof(clientAddr));
if (bytesSent == SOCKET_ERROR) {
// Handle error
WSAGetLastError();
}
sendto() returns the number of bytes sent or SOCKET_ERROR on failure.
Receiving UDP Datagrams
Datagrams are received using recvfrom(). This function fills a buffer with the received data and also provides the sender's address information:
char buffer[1024];
struct sockaddr_in senderAddr;
int addrLen = sizeof(senderAddr);
int bytesReceived = recvfrom(udpSocket, buffer, sizeof(buffer) - 1, 0, (SOCKADDR*)&senderAddr, &addrLen);
if (bytesReceived == SOCKET_ERROR) {
// Handle error
WSAGetLastError();
} else {
buffer[bytesReceived] = '\0'; // Null-terminate the received data
// Process received data in 'buffer' from sender with IP/port from senderAddr
}
recvfrom() blocks by default until a datagram is received or an error occurs.
Important Considerations
ioctlsocket() or by using WSAEventSelect() for event notification.
WSAGetLastError() to retrieve specific error codes for robust error handling.
Common UDP Errors
| Error Code | Description |
|---|---|
WSAECONNRESET |
A previous send operation failed because the remote host refused the datagram. This can happen if the destination port is not open. |
WSAETIMEDOUT |
The connection timed out. For UDP, this typically implies a packet loss or that no response was received within a reasonable timeframe (if using a custom timeout mechanism). |
WSAENETUNREACH |
The network is unreachable. |
Example Use Cases
- DNS (Domain Name System): UDP port 53 is used for quick name resolution queries.
- DHCP (Dynamic Host Configuration Protocol): Used for IP address assignment.
- VoIP and Streaming: Real-time audio and video transmission where occasional packet loss is acceptable.
- Online Gaming: Fast-paced games often use UDP for game state updates to minimize latency.