扬中网站建设怎么样,搜索引擎优化的目的是什么,网站建设 模板中心,cpa广告联盟网站建设select系统调用是用来让我们的程序监视多个文件描述符(file descriptor)的状态变化的。程序会停在select这里等待#xff0c;直到被监视的文件描述符有某一个或多个发生了状态改变。select函数原型如下#xff1a;int select(int nfds, fd_set *readfds, fd_set *writefds, f…select系统调用是用来让我们的程序监视多个文件描述符(file descriptor)的状态变化的。程序会停在select这里等待直到被监视的文件描述符有某一个或多个发生了状态改变。select函数原型如下int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);函数的最后一个参数timeout显然是一个超时时间值其类型是struct timeval *即一个struct timeval结构的变量的指针所以我们在程序里要申明一个struct timeval tv;然后把变量tv的地址tv传递给select函数。struct timeval结构如下struct timeval {long tv_sec; /* seconds */long tv_usec; /* microseconds */};第2、3、4三个参数是一样的类型 fd_set *即我们在程序里要申明几个fd_set类型的变量比如rdfds, wtfds, exfds然后把这个变量的地址rdfds, wtfds, exfds 传递给select函数。这三个参数都是一个描述符的集合第一个rdfds是用来保存这样的描述符的当描述符的状态变成可读的时系统就会告诉select函数返回同理第二个wtfds是指有描述符状态变成可写的时系统就会告诉select函数返回同理第三个参数exfds是特殊情况即描述符上有特殊情况发生时系统会告诉select函数返回。特殊情况比如对方通过一个socket描述符发来了紧急数据。如果我们程序里只想检测某个socket是否有数据可读我们可以这样fd_set rdfds; /* 先申明一个 fd_set 集合来保存我们要检测的 socket描述符 */struct timeval tv; /* 申明一个时间变量来保存时间 */int ret; /* 保存返回值 */FD_ZERO(rdfds); /* 用select函数之前先把集合清零 */FD_SET(socket, rdfds); /* 把要检测的描述符socket加入到集合里 */tv.tv_sec 1;tv.tv_usec 500000; /* 设置select等待的最大时间为1秒加500毫秒 */ret select(socket 1, rdfds, NULL, NULL, tv); /* 检测我们上面设置到集合rdfds里的描述符是否有可读信息 */if(ret 0) perror(select);/* 这说明select函数出错 */else if(ret 0) printf(超时\n); /* 说明在我们设定的时间值1秒加500毫秒的时间内socket的状态没有发生变化 */else { /* 说明等待时间还未到1秒加500毫秒socket的状态发生了变化 */printf(ret%d\n, ret); /* ret这个返回值记录了发生状态变化的描述符的数目由于我们只监视了socket这一个描述符所以这里一定ret1如果同时有多个描述符发生变化返回的就是描述符的总和了 *//* 这里我们就应该从socket这个描述符里读取数据了因为select函数已经告诉我们这个描述符里有数据可读 */if(FD_ISSET(socket, rdfds)) { /* 先判断一下socket这外被监视的描述符是否真的变成可读的了 *//* 读取socket描述符里的数据 */recv(...);}}注意select函数的第一个参数是所有加入集合的描述符值的最大那个值还要加1。比如我们创建了3个描述符int sa, sb, sc;sa socket(...); /* 分别创建3个描述符并连接到服务器上 */connect(sa,...);sb socket(...);connect(sb,...);sc socket(...);connect(sc,...);FD_SET(sa, rdfds);/* 分别把3个描述符加入读监视集合里去 */FD_SET(sb, rdfds);FD_SET(sc, rdfds);在使用select函数之前一定要找到3个描述符中的最大值是哪个我们一般定义一个变量来保存最大值取得最大socket值如下int maxfd 0;if(sa maxfd) maxfd sa;if(sb maxfd) maxfd sb;if(sc maxfd) maxfd sc;然后调用select函数ret select(maxfd 1, rdfds, NULL, NULL, tv); /* 注意是最大值还要加1 */同样的道理如果我们要检测用户是否按了键盘进行输入我们就应该把标准输入0这个描述符放到select里来检测如下FD_ZERO(rdfds);FD_SET(0, rdfds);tv.tv_sec 1;tv.tv_usec 0;ret select(1, rdfds, NULL, NULL, tv); /* 注意是最大值还要加1 */if(ret 0) perror(select);/* 出错 */else if(ret 0) printf(超时\n); /* 在我们设定的时间tv内用户没有按键盘 */else { /* 用户有按键盘要读取用户的输入 */scanf(%s, buf);}select中需要几个fd_set结构的参数用来指定你所关心的socket。 下面四个宏被定义用来使操作fd_set结构更简单 FD_CLR(s, *set) 从fd_set结构set中删掉s指明的套接字 FD_ISSET(s, *set) 判断套接字s是否在set中返回非0则证明s在set中。反之不在。 这是判断socket是否有数据可读/可写用的或者说相应的文件描述符的状态是否更改。FD_SET(s, *set) 把套接字s加入到set中 FD_ZERO(*set) 初始化set,全置0