UDP Server Example
Introduction
This example demonstrates how to create a basic User Datagram Protocol (UDP) server application using Windows Sockets (Winsock). UDP is a connectionless, unreliable transport layer protocol. It is often used for applications where speed is more important than guaranteed delivery, such as streaming media or online gaming.
This server will listen on a specified port, receive UDP datagrams, and echo the received data back to the sender.
Prerequisites
- A development environment capable of C/C++ development on Windows (e.g., Visual Studio).
- Basic understanding of C/C++ programming and Windows Sockets API.
Server Code (udp_server.c
)
Below is the C code for the UDP server. You can copy this code into a new C file (e.g., udp_server.c
) and compile it using your C++ compiler.
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define DEFAULT_PORT "8080"
#define BUFFER_SIZE 512
int main() {
WSADATA wsaData;
SOCKET listenSocket = INVALID_SOCKET;
SOCKET clientSocket = INVALID_SOCKET; // Not strictly needed for UDP, but good practice to understand
struct sockaddr_in serverAddr, clientAddr;
int clientAddrSize = sizeof(clientAddr);
char recvBuf[BUFFER_SIZE];
int bytesReceived;
// Initialize Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", WSAGetLastError());
return 1;
}
// Create a SOCKET for listening
listenSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (listenSocket == INVALID_SOCKET) {
fprintf(stderr, "socket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Setup the server address structure
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY; // Listen on all available interfaces
serverAddr.sin_port = htons(atoi(DEFAULT_PORT)); // Port to listen on
// Bind the socket to the server address
if (bind(listenSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
fprintf(stderr, "bind failed with error: %d\n", WSAGetLastError());
closesocket(listenSocket);
WSACleanup();
return 1;
}
printf("UDP Server listening on port %s...\n", DEFAULT_PORT);
// Main server loop
while (1) {
// Clear the receive buffer
memset(recvBuf, 0, BUFFER_SIZE);
// Receive data from a client
bytesReceived = recvfrom(listenSocket, recvBuf, BUFFER_SIZE, 0, (struct sockaddr *)&clientAddr, &clientAddrSize);
if (bytesReceived == SOCKET_ERROR) {
fprintf(stderr, "recvfrom failed with error: %d\n", WSAGetLastError());
// Continue to next iteration rather than exiting on a single error
continue;
}
// Convert client address to string for printing
char clientIpStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &clientAddr.sin_addr, clientIpStr, INET_ADDRSTRLEN);
printf("Received %d bytes from %s:%d\n", bytesReceived, clientIpStr, ntohs(clientAddr.sin_port));
printf("Data: %.*s\n", bytesReceived, recvBuf);
// Echo the data back to the client
int bytesSent = sendto(listenSocket, recvBuf, bytesReceived, 0, (struct sockaddr *)&clientAddr, clientAddrSize);
if (bytesSent == SOCKET_ERROR) {
fprintf(stderr, "sendto failed with error: %d\n", WSAGetLastError());
continue;
}
printf("Sent %d bytes back to %s:%d\n", bytesSent, clientIpStr, ntohs(clientAddr.sin_port));
}
// Cleanup (though this loop is infinite, this is for completeness)
closesocket(listenSocket);
WSACleanup();
return 0;
}
Compilation and Linking:
If you are using Visual Studio, create a new C++ console application project and add this code. The compiler should automatically link the Winsock library. If compiling from the command line (e.g., using MinGW or Visual Studio's developer command prompt), you might need to explicitly link:
cl udp_server.c /link ws2_32.lib
or
gcc udp_server.c -lws2_32 -o udp_server.exe
How to Run
- Compile the C code using your compiler.
- Run the compiled executable (e.g.,
udp_server.exe
) on your Windows machine. - The server will start listening on port 8080.
Testing the Server
You can test the UDP server using a UDP client application. A simple UDP client example is also available.
Alternatively, you can use tools like:
- Netcat (nc): If you have Netcat installed, you can send data to the server:
echo "Hello UDP Server" | nc -u 127.0.0.1 8080
The server should print the received message and echo it back. Netcat might show the echoed response depending on its configuration.
Key Winsock Functions Used
WSAStartup()
: Initializes the Winsock DLL.socket()
: Creates a socket. For UDP, we useAF_INET
(IPv4) andSOCK_DGRAM
(UDP).bind()
: Assigns a local address and port to a socket.recvfrom()
: Receives data from a UDP socket and gets the source address.sendto()
: Sends data to a specific address on a UDP socket.closesocket()
: Closes a socket.WSACleanup()
: Terminates the use of the Winsock DLL.