头文件
#include <sys/select.h>
函数原型
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
函数作用:监控指定描述符集合中哪些描述符可不可以做相应的操作(读/写)或是否有异常。
函数参数:
① nfds:最大的描述符+1。给select指定关心描述符的最大范围。
② readfds:是否有数据可读。
③ writefds:是否有数据可写。
④ exceptfds:是否存在异常。
⑤ timeout:超时时间。如果没有描述符可读、可写、有异常。则select函数将阻塞指定的时间长度。
为NULL:一直阻塞到有描述符可操作。
不为NULL,为0:select成为非阻塞函数。
不为NULL,不为0:select阻塞指定的时间长度。
函数返回值:
大于0:可读、可写或有异常的描述符总数
等于0:指定的阻塞时间到了
小于0:select有错误发生。其中信号引起的错误应该被忽略
select相关宏
select使用描述字集,典型地是一个整数数组
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); // 在fdset中清除fd的信息
intFD_ISSET(int fd,fd_set *fdset); // 若fdset中包含fd的信息,则返回真
代码示例
//循环的进行读操作
while(1)
{
char sbuf[2048];
int iRet = 0;
int fd;
fd_set fdset;
struct timeval szTimeval; //超时时间
szTimeval.tv_sec = 0; //0秒
szTimeval.tv_usec = 500; //500微秒
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
iRet = select(fd+1, &fdset, NULL, NULL, &szTimeval);
if(iRet > 0 && FD_ISSET(fd, &fdset))
{
iRet2 = recv(fd, sbuf, 2048, 0);
if(iRet2 > 0)
{
//对读到的数据进行处理
}
else
{
if((errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))
{
continue; //忽略信号引起的错误
}
else
{
//接收数据出错
perror("recv");
break;
}
}
}
else if(iRet == 0)
{
//超时
continue;
}
else
{
if((errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))
{
continue; //忽略信号引起的错误
}
else
{
//select真正出错
perror("http post select");
break;
}
}
}