该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才会唤醒它。
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);
//返回:若有就绪描述符则为其数目,若超时则为0,若出错则为-1;
struct timeval{
long tv_sec; //秒数
long tv_usec; //微秒数
};
timeout:告知内核等待所指定描述符中的任何一个就绪可花多长时间。
当timeout为NULL时,表示永远等待下去,仅在有一个描述符准备好I/O时才返回。
设置中间三个参数的例子
fd_set rset;
FD_ZERO(&rset);
FD_SET(1,&rset);
FD_SET(4,&rset);
操作fd_set的四个函数
void FD_ZERO(fd_set *fdset); //全部置0
void FD_SET(int fd, fd_set *fdset); //在fdset里,把fd置位
void FD_CLR(int fd, fd_set *fdset); //把fd复位
int FD_ISSET(int fd, fd_set *fdset); //判断fd是否设置
maxfdp1:指定待测试的描述符个数,它的值时待测试的最大描述符+1,因为描述符时从0开始数的。
例子
#include "unp.h"
int
main(int argc, char **argv)
{
int fd,n;
fd=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in servaddr;
servaddr.sin_family=AF_INET;
if(argc!=3){
printf("USAGE:<host> <port>\n");
exit(0);
}
else{
servaddr.sin_port=atoi(argv[2]);
inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
}
connect(fd,(struct sockaddr*)&servaddr,sizeof(servaddr));
char wbuf[2000],rbuf[2000];
int maxfd;
fd_set rset;
FD_ZERO(&rset);
for(;;){
FD_SET(fileno(stdin),&rset);
FD_SET(fd,&rset);
maxfd=max(fd,fileno(stdin))+1;
select(maxfd,&rset,NULL,NULL,NULL);
if(FD_ISSET(fd,&rset)){
if(read(fd,rbuf,2000)==0)
break;
fputs(rbuf,stdout);
}
if(FD_ISSET(fileno(stdin),&rset)){
if(fgets(wbuf,2000,stdin)==0)
break;
write(fd,wbuf,2000);
}
}
}