在传统的网络编程中,为了同时处理多个客户端的请求,我们通常每来一个连接就开辟一个新线程(或进程)。但当并发量激增时,线程的上下文切换会把服务器的 CPU 资源消耗殆尽。今天,我们将利用select的 I/O 多路转接机制,仅用单线程,就能轻松拿捏多个客户端的并发连接。一、 服务器端架构:监听与通信的完美分工根据课堂笔记,一个健壮的select服务器,其核心循环必须包含以下关键逻辑:备用集合机制:每次调用select前,必须用一个临时集合(tmp)拷贝原始集合(reads),防止内核篡改我们真正需要监控的集合。双重事件分支:当发生事件的 FD 是监听套接字(lfd)时,说明有新客户端连入,需要调用accept。当发生事件的 FD 不是监听套接字时,说明老客户端发来了数据,需要调用recv。【服务器端实战代码:select_server.c】#includestdio.h#includestdlib.h#includestring.h#includeunistd.h#includearpa/inet.h#includesys/select.hintmain(){// 1. 创建监听套接字intlfd=socket(AF_INET,SOCK_STREAM,0);intopt=1;setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,opt,sizeof(opt));// 端口复用// 2. 绑定本机 IP 和 端口 (笔记指定端口: 8989)structsockaddr_inserv_addr;memset(serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_port=htons(8989);serv_addr.sin_addr.s_addr=INADDR_ANY;bind(lfd,(structsockaddr*)serv_addr,sizeof(serv_addr));// 3. 开启监听listen(lfd,128);printf("🚀 select 单线程服务器启动,监听端口 8989...\n"