1. select函数
select的作用:
轮询的方式,从多个文件描述符中获取状态变化后的情况。
头文件
#include//for struct timeval#include //for select
函数原型
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
参数解释
- nfds: 要检测的文件描述符的范围,为文件最大描述符+1
- readfds: 包含所有可能因状态变成可读而触发select函数返回的文件描述符
- writefds: 包含所有可能因状态变成可写而触发select函数返回的文件描述符
- exceptfds: 包含所有可能因状态发生异常而触发select函数返回的文件描述符
void FD_CLR(int fd, fd_set *set); //将fd在set中去除void FD_SET(int fd, fd_set *set); //将fd添加到set中int FD_ISSET(int fd, fd_set *set); //检查set中fd是否有状态变化void FD_ZERO(fd_set *set); //清空整个set
- timeout:
struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */};
返回值
当超时或其中一个/多个文件描述符发生变化时,此函数将返回,返回值:
- -1: 函数执行出错
- 0: 超时,并将时间结构体清空为0
0: 状态变化的文件描述符的个数
基本实例
fd_set rdfds; struct timeval tv;int rtn = 0;FD_ZERO(&rdfds); //清空fd_setFD_SET(socket, &rdfds); //将要检测的socket描述符加入到fd_set集合中tv.tv_sec = 2;tv.tv_usec = 1000; //设置超时时间为2s+1msrtn = select(socket+1, &rdfds, NULL, NULL, &tv);if(rtn < 0) perror("select");else if(0 == rtn) printf("timeout\n");else{ printf("rtn = %d\n", rtn); //查看有多少个文件描述符发生了变化 if(FD_ISSET(socket, &rdfds)) //判断下这个socket是否状态真的变成了可读 { recv(...); }}
2. select做时间函数
void time_delay(int seconds){ struct timeval tv; int err; tv.tv_sec = seconds; //超时时间 tv.tv_usec = 0; do { err = select(0,NULL,NULL,NULL,&tv); //将nfds设置为0即为超时函数 }while(err<0 && errno==EINTR); //}