使用select实现的TCP并发服务器端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #define MAX_CLIENTS 10 #define BUFFER_SIZE 1024 // 客户端处理函数 void *handle_client(void *arg) { int client_fd = *(int *)arg; char buffer[BUFFER_SIZE]; int bytes_read; // 接收客户端数据 while ((bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0)) > 0) { buffer[bytes_read] = '\0'; printf("Received from client: %s\n", buffer); // 发送响应给客户端 send(client_fd, buffer, bytes_read, 0); } // 关闭客户端连接 close(client_fd); return NULL; } int main() { int server_fd, client_fd; struct sockaddr_in server_addr, client_addr; socklen_t addr_size; fd_set readfds; int max_fd; int i; // 创建socket server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd == -1) { perror("socket"); exit(1); } // 设置服务器地址结构 server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(8888); // 绑定socket到地址 if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(1); } // 监听连接 if (listen(server_fd, MAX_CLIENTS) == -1) { perror("listen"); exit(1); } printf("Server is listening on port 8888...\n"); while (1) { // 清空文件描述符集合 FD_ZERO(&readfds); // 将服务器socket添加到集合中 FD_SET(server_fd, &readfds); max_fd = server_fd; // 等待客户端连接 if (select(max_fd + 1, &readfds, NULL, NULL, NULL) == -1) { perror("select"); exit(1); } // 如果服务器socket准备好了,则接受新的连接 if (FD_ISSET(server_fd, &readfds)) { addr_size = sizeof(client_addr); client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_size); if (client_fd == -1) { perror("accept"); exit(1); } printf("New client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 为新的客户端创建一个新的线程 pthread_t thread_id; if (pthread_create(&thread_id, NULL, handle_client, &client_fd) != 0) { perror("pthread_create"); exit(1); } } } // 关闭服务器socket close(server_fd); return 0; }
使用poll实现TCP客户端中发送数据和接收数据的并发执行
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <poll.h> #define BUFFER_SIZE 1024 int main() { int client_fd; struct sockaddr_in server_addr; char buffer[BUFFER_SIZE]; struct pollfd fds[2]; // 0: stdin, 1: client_fd int ret; // 创建socket client_fd = socket(AF_INET, SOCK_STREAM, 0); if (client_fd == -1) { perror("socket"); exit(1); } // 设置服务器地址结构 server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器IP地址 server_addr.sin_port = htons(8888); // 服务器监听端口 // 连接到服务器 if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("connect"); exit(1); } // 设置poll监听stdin和client_fd fds[0].fd = STDIN_FILENO; fds[0].events = POLLIN; fds[1].fd = client_fd; fds[1].events = POLLIN; while (1) { ret = poll(fds, 2, -1); // 等待事件发生,-1表示无限期等待 if (ret == -1) { perror("poll"); exit(1); } // 如果stdin准备好了,则读取用户输入并发送给服务器 if (fds[0].revents & POLLIN) { fgets(buffer, BUFFER_SIZE, stdin); send(client_fd, buffer, strlen(buffer), 0); } // 如果client_fd准备好了,则接收服务器响应 if (fds[1].revents & POLLIN) { int bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0); if (bytes_read <= 0) { printf("Server disconnected\n"); break; } buffer[bytes_read] = '\0'; printf("Received from server: %s\n", buffer); } } // 关闭客户端socket close(client_fd); return 0; }