问题:可以通过select()函数来扩展server的功能吗?如果是,如何实现?目前服务端瓶颈分析服务器大部分时间处于等待状态,无法发挥主机(设备)的最大性能while(1){//阻塞,等待客户端连接client=accept(server,(structsockaddr*)&caddr,&asize);printf("客户端:%d\n",客户端);do{//阻塞,等待客户端数据r=recv(client,buf,sizeof(buf),0);if(r>0){printf("接收:%s\n",buf);if(strcmp(buf,"quit")!=0){len=send(client,buf,r,0);}else{休息;}}}而(r>0);close(client);}解决方法:阻塞轮询首先通过select()函数监听服务器server_fd,目标事件为“连接”(读取)。当事件发生(客户端连接)时,调用accept()接受连接,将client_fd加入监听范围,目标事件为“数据接收”(读)循环,查看每个监听的文件描述符是否有事件发生。while(1){rset=reads;实现逻辑的实现方法num=select(max+1,&rset,0,0,&timeout);如果(num>0){inti=0;for(i=1;i<=max;++i){//注意0被命令行占用,下标从1开始遍历if(FD_ISSET(i,&rset)){if(i==server){//acceptandaddclienttofd_set}else{//通过i(fd)从client读取数据}}}}}实现关键的动态调整需要被监控的文件描述符当接收到客户端连接时,客户端文件描述符被添加到监控变量(fd_set)中。当发现客户端断开连接时,将客户端文件描述符从监控变量(fd_set)中移除//添加监控if(client>-1){FD_SET(client,&reads);最大值=(客户端>最大值)?客户:最大;printf("client:%d\n",client);}//消除监听if(r==-1){FD_CLR(i,&reads);close(i);}动态调整需要监控的文件描述符个数,保证每个需要监控的文件描述符都能轮询到max=(client>max)?client:maxprogramming实验:改进的服务器>#include#includeintserver_handler(intserver){structsockaddr_inaddr={0};socklen_tasize=sizeof(addr);返回接受(服务器,(structsockaddr*)&addr,&asize);}intclient_handler(intclient){charbuf[32]={0};intret=read(client,buf,sizeof(buf)-1);如果(ret>0){buf[ret]=0;printf("接收:%s\n",buf);if(strcmp(buf,"quit")!=0){ret=write(client,buf,ret);}else{返回-1;}}returnret;}intmain(){intserver=0;结构sockaddr_insaddr={0};整数最大值=0;整数=0;fd_set读取={0};fd_settemps={0};结构timeval超时={0};服务器=套接字(PF_INET,SOCK_STREAM,0);if(server==-1){printf("服务器套接字错误\n");返回-1;}saddr.sin_family=AF_INET;saddr.sin_addr.s_addr=htonl(INADDR_ANY);saddr.sin_port=htons(8888);if(bind(server,(structsockaddr*)&saddr,sizeof(saddr))==-1){printf("服务器绑定错误\n");返回-1;}如果(听(服务器,1)==-1){printf("服务器监听错误\n");返回-1;}printf("服务器启动成功\n");FD_ZERO(&读取);FD_SET(服务器,读取);最大值=服务器;while(1){temps=读取;timeout.tv_sec=0;timeout.tv_usec=10000;num=select(max+1,&temps,0,0,&timeout);如果(num>0){inti=0;for(i=1;i<=max;++i){if(FD_ISSET(i,&temps)){if(i==server){intclient=server_handler(server);}if(client>-1){FD_SET(client,&reads);最大值=(客户端>最大值)?客户:最大;printf("接受客户端:%d\n",客户端);}}else{intr=client_handler(i);如果(r==-1){FD_CLR(i,&reads);关闭(我);}}}}}}return0;}思考:改进后的服务器是否还有优化空间?select()是否特定于Linux()系统?