细谈select函数(C语言)

细谈select函数(C语言)nbsp nbsp nbsp nbsp nbsp nbsp Select 在 Socket 编程中还是比较重要的 可是对于初学 Socket 的人来说都不太爱用 Select 写程序 他们只是习惯写诸如 connect accept recv 或 recvfrom 这样的阻塞程序 所谓阻塞方式 block 顾名思义 就是进程或是线程执行到这些函数时必须等待某个事件的发生 如果事件没有发生 进程或线程就被阻塞 函数不能立即返回 可是使用 Select 就可以完成非阻塞 所谓非阻塞方式 non block 就是进程或线程执行此函数时不必非要等待事件的发生 一旦执行肯定返回 以返回值的不

      Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。

 

Select的函数格式:

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout);

先说明两个结构体:


第一,struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(filedescriptor),即文件句柄,这可以是我们所说的普通意义的文件,当然Unix下任何设备、管道、FIFO等都是文件形式,全部包括在内,所以毫无疑问一个socket就是一个文件,socket句柄就是一个文件描述符。fd_set集合可以通过一些宏由人为来操作,比如清空集合FD_ZERO(fd_set *),将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set*),将一个给定的文件描述符从集合中删除FD_CLR(int,fd_set*),检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。

第二,struct timeval是一个大家常用的结构,用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。

具体解释select的参数:
int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。

fd_set * readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。

fd_set * writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。

fd_set * errorfds同上面两个参数的意图,用来监视文件错误异常。

struct timeval * timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。

返回值:返回状态发生变化的描述符总数。
负值:select错误













正值:某些文件可读写或出错

0:等待超时,没有可读写或错误的文件

 

select举例:

①读取键盘输入值,超时间隔2.5秒,输出用户输入的字符个数。

 

 

 

②利用select而不是fork来解决socket中的多客户问题。

 

服务器端:

 

客户端:

  

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230624.html原文链接:https://javaforall.net

(0)
上一篇 2026年2月12日 下午8:01
下一篇 2026年2月12日 下午8:22


相关推荐

  • linux wifi驱动框架_嵌入式Linux驱动开发教程

    linux wifi驱动框架_嵌入式Linux驱动开发教程对于SDIO接口的wifi,首先,它是一个sdio的卡的设备,然后具备了wifi的功能,所以,注册的时候还是先以sdio的卡的设备去注册的。然后检测到卡之后就要驱动他的wifi功能了,显然,他是用sdio的协议,通过发命令和数据来控制的。下面先简单回顾一下SDIO的相关知识:一、SDIO相关基础知识解析1、SDIO接口    SDIO故名思义,就是SD的I/O接口(in

    2022年10月3日
    4
  • pycharm中的注释_java中单行注释

    pycharm中的注释_java中单行注释”””注释””””’注释”’\#注释前两种不是真正的注释,知识字符串的另一种表现形式,例如会被用于写__doc__等长字符串的时候起到保留格式的目的,虽然能够完成注释功能,但实际上还是字符串。按ctrl+/即可快速注释代码块ps.转载出处作者已注销账号…

    2022年8月26日
    8
  • go语言环境搭建_如何搭建语言培训平台

    go语言环境搭建_如何搭建语言培训平台因为项目的原因,要用到go语言,所以自学了一下。要想学习一门语言,首先必须搭建 语言的环境,go也一样,我这边是采用源码安装的。1. 下载安装包,如果觉得翻墙麻烦,可以直接在Golang中国社区下载安装包 http://www.golangtc.com/download2.假设我们在包解压到 /home/work/dev/package/go目录下, 

    2022年10月12日
    4
  • 关于内存警告

    关于内存警告

    2022年1月26日
    58
  • js 保留2位小数

    js 保留2位小数Math floor 15 7784514000 100 100 输出结果为 15 77https www jb51 net article 134067 htm

    2026年3月18日
    2
  • html网页中加入音乐播放器,[HTML5]简单网页本地音乐播放器[通俗易懂]

    html网页中加入音乐播放器,[HTML5]简单网页本地音乐播放器[通俗易懂]既然HTML5提出与本地交互方便,就想写个HTML5的本地音乐播放器。一开始问题主要集中在怎么读取本地文件路径,我想肯定可以用JS实现去操作本地文件(因为node.js很容易实现读取本地文件,但是原生JS怎么写不太清楚),不过简单一点就用这样只能读取一个,我想做的是最好是把一个文件夹中的都取出来,然后参考http://sapphion.com/2011/11/html5-folder-upload…

    2022年6月21日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号