select()函数主要是建立在fd_set类型的基础上的。fd_set(它比较重要所以先介绍一下)是一组文件描述字(fd)的集合,它用一位来表示一个fd(下面会仔细介绍),对于fd_set类型通过下面四个宏来操作:

fd_set set;

FD_ZERO(&set);       /* 将set清零使集合中不含任何fd*/

FD_SET(fd, &set);    /* 将fd加入set集合 */

FD_CLR(fd, &set);    /* 将fd从set集合中清除 */

FD_ISSET(fd, &set);  /* 测试fd是否在set集合中*/

过去,一个fd_set通常只能包含<32的fd(文件描述字),因为fd_set其实只用了一个32位矢量来表示fd;现在,UNIX系统通常会在头文件<sys/select.h>中定义常量FD_SETSIZE,它是数据类型fd_set的描述字数量,其值通常是1024,这样就能表示<1024的fd。根据fd_set的位矢量实现,我们可以重新理解操作fd_set的四个宏:

fd_set set;

FD_ZERO(&set);      /*将set的所有位置0,如set在内存中占8位则将set置为

00000000*/

FD_SET(0, &set);    /* 将set的第0位置1,如set原来是00000000,则现在变为10000000,这样fd==1的文件描述字就被加进set中了 */

FD_CLR(4, &set);    /*将set的第4位置0,如set原来是10001000,则现在变为10000000,这样fd==4的文件描述字就被从set中清除了 */

FD_ISSET(5, &set);  /* 测试set的第5位是否为1,如果set原来是10000100,则返回非零,表明fd==5的文件描述字在set中;否则返回0*/

―――――――――――――――――――――――――――――――――――――――

注意fd的最大值必须<FD_SETSIZE。

―――――――――――――――――――――――――――――――――――――――

select函数的接口比较简单:

int select(int nfds, fd_set *readset, fd_set *writeset,

fd_set* exceptset, struct timeval *timeout);

功能:

测试指定的fd可读?可写?有异常条件待处理?

参数:

nfds

需要检查的文件描述字个数(即检查到fd_set的第几位),数值应该比三组fd_set中所含的最大fd值更大,一般设为三组fd_set中所含的最大fd值加1(如在readset,writeset,exceptset中所含最大的fd为5,则nfds=6,因为fd是从0开始的)。设这个值是为提高效率,使函数不必检查fd_set的所有1024位。

readset

用来检查可读性的一组文件描述字。

writeset

用来检查可写性的一组文件描述字。

exceptset

用来检查是否有异常条件出现的文件描述字。(注:错误不包括在异常条件之内)

timeout

有三种可能:

1.        timeout=NULL(阻塞:直到有一个fd位被置为1函数才返回)

2.        timeout所指向的结构设为非零时间(等待固定时间:有一个fd位被置为1或者时间耗尽,函数均返回)

3.        timeout所指向的结构,时间设为0(非阻塞:函数检查完每个fd后立即返回)

返回值:

返回对应位仍然为1的fd的总数。

Remarks:

三组fd_set均将某些fd位置0,只有那些可读,可写以及有异常条件待处理的fd位仍然为1。

使用select函数的过程一般是:

先调用宏FD_ZERO将指定的fd_set清零,然后调用宏FD_SET将需要测试的fd加入fd_set,接着调用函数select测试fd_set中的所有fd,最后用宏FD_ISSET检查某个fd在函数select调用后,相应位是否仍然为1。

以下是一个测试单个文件描述字可读性的例子:

int isready(int fd)

{

int rc;

fd_set fds;

struct timeval tv;

FD_ZERO(&fds);

FD_SET(fd,&fds);

tv.tv_sec = tv.tv_usec = 0;

rc = select(fd+1, &fds, NULL, NULL, &tv);

if (rc < 0)   //error

return -1;

return FD_ISSET(fd,&fds) ? 1 : 0;

}

下面还有一个复杂一些的应用:

//这段代码将指定测试Socket的描述字的可读可写性,因为Socket使用的也是fd

uint32 SocketWait(TSocket *s,bool rd,bool wr,uint32 timems)

{

fd_set rfds,wfds;

#ifdef _WIN32

TIMEVAL tv;

#else

struct timeval tv;

#endif   /* _WIN32 */

FD_ZERO(&rfds);

FD_ZERO(&wfds);

if (rd)     //TRUE

FD_SET(*s,&rfds);   //添加要测试的描述字

if (wr)     //FALSE

FD_SET(*s,&wfds);

tv.tv_sec=timems/1000;     //second

tv.tv_usec=timems%1000;     //ms

for (;;) //如果errno==EINTR,反复测试缓冲区的可读性

switch(select((*s)+1,&rfds,&wfds,NULL,

(timems==TIME_INFINITE?NULL:&tv)))  //测试在规定的时间内套接口接收缓冲区中是否有数据可读

{                                              //0--超时,-1--出错

case 0:     /* time out */

return 0;

case (-1):    /* socket error */

if (SocketError()==EINTR)

break;

return 0; //有错但不是EINTR

default:

if (FD_ISSET(*s,&rfds)) //如果s是fds中的一员返回非0,否则返回0

return 1;

if (FD_ISSET(*s,&wfds))

return 2;

return 0;

};

}

select()用法相关推荐

  1. python+selenium七:下拉框、选项框、select用法

    # from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains im ...

  2. 专科 java转go 翱翔之路(二)基础语法:匿名组合,方法,接口,map,json,异常处理,channel管道,select用法

    2.4 面向对象编程 2.4.1匿名组合 type Person struct {id intname stringage int }type Student struct {Person //只有类 ...

  3. MyBatis中select用法

    使用MyBatis时,只需要在XML中添加一个select元素,写一个SQL,再做一些简单的配置就可以实现映射 使用XML方式 MyBatis支持用接口来调用方法,通过参数注解@param设置参数名字 ...

  4. GO select用法详解

    golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作. 在执行select语句的时候,运行时系统会自上而下地判断每个case中的发送或接收操作是否可以被立即执行( ...

  5. MySQL:case函数和if函数的select用法(超详细)

    case在select语句中的第一种用法: 这种写法只是针对某一个单一属性的具体值来做判断select id,name,(case sex when 0 then '男' when 1 then '女 ...

  6. INSERT INTO SELECT 用法

    INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中.        其基本的书写格式为: INSERT INTO table2 (c1,c2,c3...) S ...

  7. shell编程中的select用法

    select 语句 select表达式是bash的一种扩展应用,擅长于交互式场合.用户可以从一组不同的值中进行选择: select var in ... ; dobreak; done .... no ...

  8. 【golang】Go语言学习-select用法

    golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作. 示例: ch1 := make (chan in ...

  9. java爬取网页内容 简单例子(2)——附jsoup的select用法详解

    [背景] 在上一篇博文 java爬取网页内容 简单例子(1)--使用正则表达式 里面,介绍了如何使用正则表达式去解析网页的内容,虽然该正则表达式比较通用,但繁琐,代码量多,现实中想要想出一条简单的正则 ...

  10. python中select用法_Python select及selectors模块概念用法详解

    1. select模块 针对select,要先理解其他几个概念: 文件描述符: 文件描述符在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表.当程序打开 ...

最新文章

  1. Python 越被黑越红?2 万程序员这么说......
  2. RocketMQ实现原理
  3. c语言程序设计江宝钏第九章,C语言程序设计 (江宝钏 著) 清华大学出版社 第9章习题答案1...
  4. 上海工程技术大学计算机通信与网络,上海工程技术大学
  5. 如何用while循环输出十行十列变色★☆
  6. Django:静态文件staticfiles
  7. 沃兹批评苹果避税:纳税还不如我积极
  8. 对于vertical-align的学习
  9. 关于机器人方面的sci论文_化学教学论文发表【期刊论文】化学教学论文发表
  10. 分享两款在线教育教学管理系统源码
  11. 自制小型USB TO TTL串口工具
  12. 【GIT】git 提交代码正确步骤
  13. Windows server 2012 R2 无法安装vc2015
  14. 移动端html页面显示图表,HTML5移动端数据图表组件调研
  15. 计算机考研408二战
  16. 第一天 游戏策划学习
  17. 最新资料!工银亚洲开户见证业务受理网点(深圳地区)
  18. 8Manage PPM,助力北京测威提升项目运营效益
  19. Windows Mobile 播放声音文件
  20. AutoCAD Civil3D 2023安装图文教程及下载

热门文章

  1. C语言学习笔记——n个小孩围成一圈,顺序排号,报数报到5的出局...
  2. cfa考试可以用计算机吗,CFA考试可以用哪种计算器?
  3. 鱿鱼游戏官方都没做出PC端游和手游,B站小伙率先把活儿整齐了
  4. C#AE练习 (1)地图、图层加载及图层的属性访问
  5. 【惯性导航姿态仪】02 磁传感器的简易标定说明
  6. 我的第一个nw.js爬虫
  7. 神奇的不可见空格200b导致代码异常
  8. Activity中不走onStop的问题
  9. 4.7 Randomization and Restart Strategies
  10. sass-loader高版本问题,解析就报错!!