http://www.cnblogs.com/wolflion/archive/2011/07/13/2539137.html

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

fd_set set;

FD_ZERO(&set);

FD_SET(fd, &set);

FD_CLR(fd, &set);

FD_ISSET(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);

FD_SET(0, &set);

FD_CLR(4, &set);

FD_ISSET(5, &set);

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

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

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

select函数的接口比较简单:

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

fd_set* exceptset, struct tim *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 tim 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

TIM tv;

#else

struct tim tv;

#endif

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=timems00;     //ms

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

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

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

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

case 0:

return 0;

case (-1):

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;

};

}

fd_set 用法的更多相关文章

  1. Linux下I/O多路转接之select --fd_set

    fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...

  2. socket基本

    fd_set用法: http://blog.sina.com.cn/s/blog_5c8d13830100erzs.htm socket连接: lpszHost="127.0.0.1&quo ...

  3. select、poll和epoll机制

    一.参考网址 1.select函数及fd_set介绍 2.linux select 函数和 fd_set 用法 2.select.poll和epoll的区别 3.利用select实现IO多路复用TCP ...

  4. Linux C++实现一服务器与多客户端之间的通信

    通过网络查找资料得到的都是一些零碎不成体系的知识点,无法融会贯通.而且需要筛选有用的信息,这需要花费大量的时间.所以把写代码过程中用到的相关知识的博客链接附在用到的位置,方便回顾. 1.程序流程 服务 ...

  5. linux c语言 select函数用法

    linux c语言 select函数用法 表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<unis ...

  6. 网络通信 --> select()用法

    select()用法 头文件 #include <sys/time.h> #include <sys/types.h> #include <unistd.h> 定义 ...

  7. select()函数用法二

    Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect.accept.recv或recvfrom这样的阻塞程序 ...

  8. (转) c/c++调用libcurl库发送http请求的两种基本用法

    libcurl主要提供了两种发送http请求的方式,分别是Easy interface方式和multi interface方式,前者是采用阻塞的方式发送单条数据,后者采用组合的方式可以一次性发送多条数 ...

  9. select,poll,epoll用法

    http://blog.csdn.net/sunboy_2050/article/details/6126712 select用法 #include <sys/time.h>       ...

随机推荐

  1. c++ algorithm 的用法

    1 , accumulate()template<class _II, class _Ty> inline_Ty accumulate(_II _F, _II _L, _Ty _V){fo ...

  2. Android 源码VecotorDrawable

    1 R.styleable.VectorDrawable_viewportWidth 该资源的名字并非VectorDrawable_viewportWidth 而是 attrs.xml 下的声明 &l ...

  3. linux文件权限位SUID,SGID,sticky的设置理解

    SUID含义:文件的该位被设置为1,在该文件被执行时,该文件将以所有者的身份运行,也就是说无论谁来           执行这个文件,他都有文件所有者的特权,如果所有者是root的话,那么执行人就有超 ...

  4. TweenMax动画库学习(一)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  5. php常量运用注意

    多个文件引入,常量重复定义会失效,后者无法重复定义...靠

  6. apache、php隐藏头信息的方法

    本文介绍下,在apache与php中隐藏头部信息的方法,有需要的朋友参考下. 一.apache隐藏头部信息 apache 的 httpd.conf 有两个配置可以控制是否显示服务器信息给用户.Serv ...

  7. php入门变量之变量的间接引用、连接字符串和连接赋值运算符

    [1]变量的间接引用: <?php $a = 'b'; $$a = '123'; echo $b; ?> 上面的输出结果是123 我们可以看到在第二行代码中多了一个$,并通过指定的名称访问 ...

  8. 移植openssl

    1.官网(ftp://ftp.openssl.org/source/old/0.9.x/)下载openssl-0.9.8k.tar.gz2.交叉编译openssl CC=arm-hisiv400-li ...

  9. ubuntu安装kernel3.10.34

    参考http://www.linuxidc.com/Linux/2014-03/98818.htm 32位系统安装 wget kernel.ubuntu.com/~kernel-ppa/mainlin ...

  10. 2016 系统设计第一期 (档案一)MVC 引用 js css

    @Styles.Render("~/Bootstrap/css/bootstrap-theme.css") @Scripts.Render("~/jQuery/jquer ...