select
//select(maxfd,rset,wset,eset,timeout); r读,w写,e错误,timeout多长时间轮询一次
//有事件就返回
//rset--> uL fds_bites[_FD_SIZE/(8*sizeof(long))]
//#define _FD_SIZE 1024 默认值1024,内核定义
fd_set rfds , rset;
FD_ZERO(&rfds);
FD_SET(sockfd,&rfds);
int maxfd=sockfd;
while(1){
rset=rfds;
int nready=select(maxfd+1,&rset,NULL,NULL,NULL);//事件个数
if(FD_ISSET(sockfd,&rset)){
int clientfd=accept(sockfd,(struct sockaddr*)&clientaddr,&len);
FD_SET(clientfd,&rfds);
maxfd=clientfd;
}
int i=0;
for(i=sockfd+1;i<=maxfd;i++){
if(FD_SET(i,&rset)){
// 读事件,发送
//FD_CLR(i,&rfds);close(i);
//第一层bit_set。第二层系统io
}
}
}
缺点:
内核每一次都需要拷贝rset,拷贝整个,有很多不需要;IO数量有限制;参数较多,许都需要单独维护