UDP (User Datagram Protocol)
The User Datagram Protocol (UDP) is a connectionless communication protocol that provides a simple, but unreliable, way to send messages over a network. UDP is commonly used for applications where speed is more important than guaranteed delivery, such as streaming media, online gaming, and DNS queries.
Key Concepts
- Connectionless: UDP does not establish a persistent connection between the sender and receiver. Each datagram is sent independently.
- Unreliable: UDP does not guarantee that datagrams will arrive at their destination, nor does it guarantee their order of arrival. Lost or out-of-order datagrams are not retransmitted by the protocol.
- Datagrams: Data is sent in discrete units called datagrams. Each datagram is self-contained and includes source and destination port numbers.
- Low Overhead: UDP has minimal header information, resulting in lower latency and higher throughput compared to TCP for certain applications.
Core Winsock Functions for UDP
WSASocket
Creates a socket that can be used for UDP communication. When creating a UDP socket, specify AF_INET or AF_INET6 for the address family and SOCK_DGRAM for the socket type.
SOCKET WSAAPI WSASocket(
[in] int af,
[in] int type,
[in] int protocol,
[in, out, optional] LPWSAPROTOCOL_INFO lpProtocolInfo,
[in] GROUP g,
[in] DWORD dwFlags
);
bind
Associates a local address and port number with a socket. For UDP, this is essential to allow the application to receive datagrams on a specific port.
int bind(
[in] SOCKET s,
[in] const struct sockaddr *name,
[in] int namelen
);
sendto
Sends a UDP datagram to a specific destination address and port. This function is used for both connectionless and connection-oriented sockets, but is the primary sending mechanism for connectionless UDP sockets.
int sendto(
[in] SOCKET s,
[in] const char *buf,
[in] int len,
[in] int flags,
[in] const struct sockaddr *to,
[in] int tolen
);
recvfrom
Receives a UDP datagram from a remote host and retrieves the sender's address. This function is crucial for reading incoming UDP data.
int recvfrom(
[in] SOCKET s,
[out] char *buf,
[in] int len,
[in] int flags,
[out] struct sockaddr *from,
[in, out, optional] int *fromlen
);
Example: Simple UDP Sender
This snippet illustrates sending a simple UDP message. A full example would include Winsock initialization and error handling.
// Assume 'udpSocket' is a valid UDP socket created with WSASocket()
// Assume 'serverAddr' is a populated SOCKADDR_IN structure with destination IP and port
char message[] = "Hello from UDP client!";
int messageLen = strlen(message);
int bytesSent = sendto(udpSocket, message, messageLen, 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (bytesSent == SOCKET_ERROR) {
// Handle error
}
Example: Simple UDP Receiver
This snippet illustrates receiving a UDP message. A full example would include Winsock initialization, binding the socket, and error handling.
// Assume 'udpSocket' is a valid UDP socket created with WSASocket() and bound to a port
// Assume 'buffer' is a char array of sufficient size to hold incoming data
// Assume 'clientAddr' is a SOCKADDR_IN structure to store sender's address
int bufferSize = 1024;
char buffer[bufferSize];
int clientAddrLen = sizeof(clientAddr);
int bytesReceived = recvfrom(udpSocket, buffer, bufferSize - 1, 0, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (bytesReceived == SOCKET_ERROR) {
// Handle error
} else {
buffer[bytesReceived] = '\0'; // Null-terminate the received data
// Process the received message in 'buffer' from the address in 'clientAddr'
}