How to implement UDP sockets in C
Server-side
Explanation
Include the header file <sys/socket.h> and arpa/inet.h:
#include <sys/socket.h>
#include <arpa/inet.h>
Create a socket that returns a socket descriptor. This is used to refer to the socket later on in the code:
int socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
The server-side code keeps the address information of both the server and the client in the variable server_addr (a struct of type sockaddr_in). Initialize the server address by the port and IP:
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(2000);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
Bind socket descriptor to the server address:
bind(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr);
Unlike TCP, the server-side does not wait for a client to connect and, therefore, does not receive the client’s address prior to sending and receiving data. Instead, the server receives information about the client when it receives data using the recvfrom() method:
int client_struct_length = sizeof(client_addr);
recvfrom(socket_desc, client_message, sizeof(client_message), 0,
(struct sockaddr*)&client_addr, &client_struct_length);
The client’s information, stored in the variable client_addr of type sockaddr_in, is then used to send data to the same client:
sendto(socket_desc, server_message, strlen(server_message), 0,
(struct sockaddr*)&client_addr, client_struct_length);
Close the socket to end the communication:
close(socket_desc);
Client-side
Explanation
Include header files, create a socket, and initialize the server’s address information in a variable of type sockaddr_in (similarly to how it was done at the server-side):
#include <sys/socket.h>
#include <arpa/inet.h>
int socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(2000);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
Unlike TCP, when the client sends and receives data using sendto() and recvfrom(), the server’s information has to be given every time:
sendto(socket_desc, client_message, strlen(client_message), 0,
(struct sockaddr*)&server_addr, server_struct_length);
recvfrom(socket_desc, server_message, sizeof(server_message), 0,
(struct sockaddr*)&server_addr, &server_struct_length);
A deadlock will occur if both the client and the server are waiting for each other’s message at
recvfrom().
Client-server app
The following client-server application enables a client to connect to a server and send only one message. The server replies with the same message converted to uppercase letters and the communication terminates.
Instructions
- Click the Run button in the widget below and execute the command for the Server. If the socket is created successfully, the message Listening for incoming messages… will be displayed.
- Press the
+button to open another terminal tab and execute the Client’s command. - Enter a message in the Client tab that is sent to the Server.
- The Server’s response will be shown in the Client’s tab.
| Server | Client |
|---|---|
usercode/server |
usercode/client |
Free Resources