In network programming, UDP (User Datagram Protocol) is a connectionless transport layer protocol. Unlike TCP, UDP does not guarantee the order of packet delivery and does not provide a retransmission mechanism, making it suitable for scenarios that require high speed but low reliability, such as video streaming and online gaming.
This article will introduce how to perform UDP programming using the C language, including creating UDP sockets, sending and receiving data, and a simple example program.
1. Basics of UDP Sockets
In C language, we can use the <span>socket</span> function to create a UDP socket. The general steps to create a UDP socket are as follows:
- Include the necessary header files.
- Create a socket.
- Bind the socket to a local address and port.
- Use
<span>sendto</span>and<span>recvfrom</span>functions for data transmission and reception.
1.1 Including Header Files
First, we need to include some standard library and network library header files:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
1.2 Creating a UDP Socket
We can create a UDP socket by calling <span>sockfd = socket(AF_INET, SOCK_DGRAM, 0)</span>, where:
<span>AF_INET</span>indicates the IPv4 address family.<span>SOCK_DGRAM</span>indicates the use of datagram mode (i.e., UDP).
1.3 Binding Address and Port
To allow our program to listen for messages on a specific port, we need to bind it to a local IP address and port. We can use the <span>sockaddr_in</span> structure to set this information.
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET; // IPv4
server_addr.sin_addr.s_addr = INADDR_ANY; // Accept messages from any sender
server_addr.sin_port = htons(port); // Set port number
bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
2. UDP Sending and Receiving
2.1 Sending Data
To send data to a specified target, we can use the <span>sendto()</span> function, which has the following prototype:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
Where the parameters include:
<span>sockfd</span>: Socket descriptor.<span>buf</span>: Buffer of data to be sent.<span>len</span>: Length of the data.<span>flags</span>: Usually 0.<span>dest_addr</span>: Pointer to the destination address information structure.<span>addrlen</span>: Size of the address structure.
2.2 Receiving Data
To receive data from a client or another host, we can use the <span>recvfrom()</span> function, which has the following prototype:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
3 Example Code: Simple UDP Server and Client
Below is a simple example that includes a basic implementation of a UDP server and client.
UDP Server Code Example
// udp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr, client_addr;
socklen_t addr_len;
// Create socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// Fill server information
memset(&server_addr, '\0', sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
// Bind the socket with the server address
if (bind(sockfd,(const struct sockaddr *)&server_addr,sizeof(server_addr))<0) {
perror("Bind failed");
close(sockfd);
exit(EXIT_FAILURE);
}
while(1) {
addr_len = sizeof(client_addr);
ssize_t n = recvfrom(sockfd , buffer , BUFFER_SIZE , MSG_WAITALL , (struct sockaddr *) &client_addr , &addr_len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd , buffer , n , MSG_CONFIRM , (const struct sockaddr *) &client_addr , addr_len );
}
close(sockfd);
return 0;
}
UDP Client Code Example
// udp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in servaddr;
// Create socket
if ((sockfd = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDPLITE))<0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr,'\0',sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr.s_addr);
while(1){
printf("Enter message: ");
fgets(buffer,sizeof(buffer),stdin);
sendto(sockfd,(const char *)buffer,sizeof(buffer),MSG_CONFIRM,(const struct sockaddr *)&servaddr,sizeof(servaddr));
ssize_t n=recvfrom(sockfd,(char *)buffer,BUFFER_SIZE,MSG_WAITALL,(struct sockaddr*)&servaddr,&addr_len);
buffer[n]='\0';
printf("Server : %s\n",buffer);
}
close(sockfd);
return EXIT_SUCCESS;
}
Conclusion
This article introduced how to implement data communication based on the UDP protocol in C language, including creation, binding, sending, and receiving operations. Through the examples provided, you should be able to understand the basic concepts and start building your own network applications. In actual development, please pay attention to handling error situations and potential data loss issues to ensure your application is as stable and reliable as possible.