select函数
/* According to POSIX.1-2001 */
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *set);//测试某个描述符是否在集合内
int FD_ISSET(int fd, fd_set *set);//从集合内把一个描述符移除
void FD_SET(int fd, fd_set *set);//把一个描述符加入集合
void FD_ZERO(fd_set *set);//清空描述符集合
监视readfds查看读文件描述符集合会不会被堵塞(即使end-of-file,也是可读的)。
监视writefds查看写文件描述符集合会不会被堵塞。
监视exceptfd异常文件描述符集合是否出现了异常。主要用来读取OOB数据,异常并不是指出错。
注意当一个套接口出错时,它会变得既可读又可写。
如果有了状态改变,会将其他fd清零,只有那些发生改变了的fd保持置位,以用来指示set中的哪一个改变了状态。
参数n是所有set里所有fd里,具有最大值的那个fd的值加1
struct timeval
{long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
timeval是从调用开始到select返回前,会经历的最大等待时间。
当timeval为 NULL时,会无限等待,直到被信号打断时返回1, errno 设置成 EINTR。
当timeval.tv_sec 为0并且 timeval.tv_usec为0,不等待立即返回。
当timeval.tv_sec非0 或者timeval.tv_usec非 0,等待特定时间长度, 超时返回0。
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(void)
{
fd_set rfds;
struct timeval tv;
FD_ZERO(&rfds);
FD_SET(0,&rfds);
tv.tv_sec=10;
tv.tv_usec=0;
int ret=select(1,&rfds,NULL,NULL,&tv);
if(ret==-1)
printf("error!\n");
else if(ret)
{
if(FD_ISSET(0,&rfds))
printf("fd0 data is avilable!\n");
}
else
printf("no data coming in 2 sec!\n");
return 0;
}
用select对TCP客户端代码进行修改
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<signal.h>
#include <errno.h>