Linux下UDP网络编程的三种基本模型

需积分: 50 11 下载量 89 浏览量 更新于2025-03-28 1 收藏 7.63MB RAR 举报
Linux UDP编程是一种基于用户数据报协议的网络编程方式,在Linux环境下主要利用socket编程接口实现网络通信。UDP协议与TCP协议不同,它是一种无连接的协议,提供面向事务的简单不可靠信息传送服务。UDP编程包括服务器端和客户端的实现,下面将详细介绍UDP编程的基本模型和关键知识点。 ### 1. 基本服务器模型步骤 基本的UDP服务器模型相对简单,包括以下几个步骤: - 创建套接字(socket):使用`socket()`函数创建一个新的UDP套接字。 - 绑定套接字(bind):使用`bind()`函数将套接字绑定到一个IP地址和端口上。 - 接收数据(recvfrom):使用`recvfrom()`函数等待并接收来自客户端的数据。 - 处理数据:对接收到的数据进行处理。 - 发送数据(sendto):使用`sendto()`函数将处理结果发送回客户端。 - 关闭套接字(close):使用`close()`函数关闭套接字,释放资源。 #### 代码示例: ```c #include <stdio.h> // for printf() and fprintf() #include <sys/socket.h> // for socket(), bind(), and connect() #include <arpa/inet.h> // for sockaddr_in and inet_addr() #include <stdlib.h> // for atoi() and exit() #include <string.h> // for memset() #include <unistd.h> // for close() #define RCVBUFSIZE 32 // Size of receive buffer #define MAXPENDING 5 // Maximum outstanding connection requests int main(int argc, char *argv[]) { int sockfd; // socket descriptor struct sockaddr_in echoServAddr; // Echo server address struct sockaddr_in echoClntAddr; // Client address unsigned short echoServPort; unsigned int cliAddrSize; // Address size char *servIP; // Server IP address (dotted quad) char *rbuf; // Receive buffer char servIPstr[INET_ADDRSTRLEN]; // Server IP string if ((argc < 3) || (argc > 4)) // Test for correct number of arguments { fprintf(stderr,"Usage %s <Server IP> <Echo Word> [<Echo Port>]\n", argv[0]); exit(1); } servIP = argv[1]; // First arg: server IP address (dotted quad) echoServPort = (argc == 4) ? atoi(argv[3]) : 7; // Use 7 if no port given sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // Create socket if (sockfd < 0) err_sys("socket() failed"); memset(&echoServAddr, 0, sizeof(echoServAddr)); // Zero out structure echoServAddr.sin_family = AF_INET; // Internet address family echoServAddr.sin_addr.s_addr = inet_addr(servIP); // Server IP address echoServAddr.sin_port = htons(echoServPort); // Server port // Bind the descriptor to the address if (bind(sockfd, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) err_sys("bind() failed"); // Allocate memory for the receive buffer if ((rbuf = (char *)malloc(RCVBUFSIZE)) == NULL) err_sys("malloc() failed"); cliAddrSize = sizeof(echoClntAddr); // Save size of client address while (1) // Run forever { int i; // Receive message from the client if (recvfrom(sockfd, rbuf, RCVBUFSIZE, 0, (struct sockaddr *) &echoClntAddr, &cliAddrSize) < 0) err_sys("recvfrom() failed"); printf("Received %d bytes from %s port %d\n", strlen(rbuf), inet_ntoa(echoClntAddr.sin_addr), ntohs(echoClntAddr.sin_port)); // Echo the message back to the client if (sendto(sockfd, rbuf, strlen(rbuf), 0, (struct sockaddr *) &echoClntAddr, cliAddrSize) != strlen(rbuf)) err_sys("sendto() failed"); else printf("Sent %d bytes back to %s\n", strlen(rbuf), inet_ntoa(echoClntAddr.sin_addr)); } close(sockfd); // Close the socket when done exit(0); } ``` ### 2. 循环服务器模型步骤 循环服务器模型(也称为迭代服务器)会为每个客户端请求创建一个新的进程或线程进行服务,处理完毕后,该进程或线程会被销毁。 #### 关键步骤: - 循环监听端口,接受连接请求。 - 接收到连接请求后,创建子进程或线程。 - 在子进程或线程中进行数据处理和响应。 - 处理完毕后,子进程或线程结束,主进程继续监听。 #### 代码示例略。 ### 3. 并发服务器模型步骤 并发服务器模型则与循环服务器模型不同,它通过多线程或IO多路复用技术来同时处理多个客户端请求。 #### 关键步骤: - 使用`select()`或`poll()`等IO多路复用函数来监听多个文件描述符。 - 当某个文件描述符可读时,说明某个客户端有数据到达,进行读操作。 - 根据读取的数据,进行处理并发送响应。 - 多个客户端请求可以同时进行处理。 #### 代码示例略。 ### 总结 以上即为Linux环境下UDP编程的三种主要模型。基本服务器模型适用于轻量级服务,而循环服务器模型和并发服务器模型更适合处理大量并发连接的情况。在实际开发中,根据应用场景的需要选择合适的服务器模型非常重要。UDP编程虽然相对简单,但由于其无连接特性,确保数据的完整性和可靠性需要在应用层进行更多处理。此外,多线程编程和IO多路复用技术的掌握对于实现高效稳定的UDP服务器至关重要。