这里你得尝试理解一下
select是个古老的函数。在古老的UNIX系统里面,希望用单线程处理阻塞的网络函数,比如accept, recv, send,怎么办呢?于是我们的程序员老祖宗们发明了伟大的。 首先,考虑到我们的socket是一个一个的文件流(这一点很重要),于是我们设计了这个宏,把socket和状态级 readfd, writefd, errorfd捆绑起来,用定时轮循,限制这个函数操作在一个时间片内返回,将返回结果逐一核对,分别检查accept/recv/send有关的socket是不是动作了,如果有数据或者有结果采取处理,否则操作系统可以空闲下来干点别的: readfd; FD_ZERO(&readfd); FD_SET(sockfd,&readfd); while(1){ sin_size=sizeof(struct ); /*select,第一个参数是用于检查所有socket,第二个参数检查缓冲测试区,第三个第四个也是,顺序是readfd, writefd和errorfd,最后一个参数是限制select检查用的等待时间*/ if(select(MAX_CONNECTED_NO,&readfd,NULL,NULL,(struct timeval *)0)> 0){ if((sockfd,&readfd)> 0){ /*可以进行accept了,直接放进来*/ if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1){ perror( "accept "); exit(1); } /*可以读取数据了*/ if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1){ perror( "recv "); exit(1); } if(read(client_fd,buf,MAXDATASIZE) <0){ perror( "read "); exit(1); } printf( "received a connection :%s ",buf); }/*if*/ close(client_fd); }/*select*/ }/*while*/ 这样,服务器可以不需要多线程、多进程就完成了所有socket的各种操作,比如accept,recv和send。令人惊讶的是,这样写的服务器程序稳定性和效率都远高于现在我们用的CreateProcess/CreateThread/fork/pthread_creaet等等,前辈的能耐真是让我们汗颜啊! 但愿你看明白了