一般用connect、accept、recv或recvfrom这类函数,程序阻塞,直至该套接字上接受到数据后程序才能继续运行。但是使用select函数可以实现非阻塞方式的程序。它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。

Select的函数格式:

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

fd_set可以理解成存放一些fds的集合或者池子。

fd表示文件描述符。Linux系统中任何设备都是一个文件,表示该设备的指针就是文件描述符。

函数各个入参解释如下:

<1>maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,如果是在Linux环境上运行,该参数值不能错。如果在Windows中这个参数的值无所谓,可以设置不正确。

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

<3>writesfds的含义和readfds相同,区别在于我们关心的是该文件是否可写而不是可读。当socket套接字准备发送数据时,该fd即为可写状态。

<4>errorfds,和上面两个相同,表示监听文件描述符的异常。

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

函数返回值:

负值:select错误

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

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

当建立好socket套接字fd后,使用FD_SET函数将该fd放入select函数所监听的fd集合中。FD_ZERO用来初始化集合。

下面一段伪代码简单的介绍select函数在程序中的使用方法:

int main()

{

fd_set socket_fds,int listen_fd,int result;

listen_fd = socket();

bind();listen();

FD_ZERO(&socket_fds);

FD_SET(listen_fd,&socket_fds);

while(1)

{

result = select(FD_SETSIZE,socket_fds,NULL,NULL,0);//监听listen_fd是否可读,即是否接收到数据。

if(result < 1)

{

reutrn 0;

}

for(fd = 0; fd < FD_SETSIZE; fd++)

{

if(FD_ISSET(fd,&socket_fds))//监听的某个fd可读

{

if(fd == listen_fd)//如果该fd是上面建立的套接字

{

recv();//接收数据

dosomething....

}

}

}

}

}

在更一般的使用场景中,当监听的文件描述符发生我们所期待的动作时,会调用回调函数进行数据接收和处理。有关回调函数的概念和使用方法,后面介绍~~~

C语言中select函数的使用相关推荐

  1. C语言中select函数简介及使用

    select函数用来检查套接字描述符(sockets descriptors)是否已准备好读/写,提供了一种同时检查多个套接字的方法. Linux中select函数的声明在/usr/include/x ...

  2. 关于C语言中printf函数“输出歧视”的问题

    目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...

  3. C语言中atoi()函数的用法

    C语言中atoi()函数的用法 一.学习要点: 1.int atoi(const char *str)把参数str所指向的字符串转换为一个整数: 二.代码 #include<stdio.h> ...

  4. r语言中c函数错误,R语言中c()函数与paste()函数的区别说明

    c()函数:将括号中的元素连接起来,并不创建向量 paste()函数:连接括号中的元素 例如 c(1, 2:4),结果为1 2 3 4 paste(1, 2:4),结果为"1 2" ...

  5. C语言中main函数的研究,以及对代码断点调试的研究(王爽老师 汇编语言)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 我们知道作为一个语言本身是不会有诸如从main函数开始运行这样的条件(深层次的说 底层汇编代码不会指定从mian函数开始的这样的条件,程序开始的位 ...

  6. 浅析C语言中strtol()函数与strtoul()函数的用法

    这篇文章主要介绍了浅析C语言中strtol()函数与strtoul()函数的用法,注意其将字符串转换成long型的区别,需要的朋友可以参考下 头文件: ? 1 #include <stdlib. ...

  7. c语言memcopy_C语言中memcpy 函数的用法详解

    C语言中memcpy 函数的用法详解 memcpy(内存拷贝函数) c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址 ...

  8. c语言中memcpy函数_带有示例的C中的memcpy()函数

    c语言中memcpy函数 memcpy()函数 (memcpy() function) memcpy() is a library function, which is declared in the ...

  9. c语言中 调用函数除函数名外,【单选题】在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分) A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值...

    [单选题]在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分) A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值 更多相关问题 下列关于IMOECDIS性能标 ...

最新文章

  1. Genome Research | TransBorrow:通过借用不同拼接工具的拼接结果来引导完成转录组拼接
  2. centos telnet 安装 配置
  3. Atitit usrQBK1600 技术文档的规范标准化解决方案
  4. SecureCRT 全屏切换
  5. 秒懂系列 | 史上最简单的Python Django入门教程
  6. JAVA类定义,成员类,抽象类及接口类
  7. 使用jquery datatables插件遇到fnReloadAjax的问题
  8. mockito 外部接口_mockito – Spring批处理作业的端到端测试用例
  9. 前端基础语言HTML、CSS 和 JavaScript 学习指南
  10. 读取 system serial number
  11. 几个很实用的软件 root 改机 软改 硬改 改串号 改设备 参数生成器APK 电脑软件
  12. ModifyStyle, ModifyStyleEx
  13. 【解决方法】Socket服务端退出之后端口依旧被占用
  14. 【知识兔】Ctrl+H,Word文档中超好用的快捷键
  15. SharpDevelop安装与配置
  16. uniapp app安卓系统真机调试
  17. windows输入法第一次输入的时候有时候不给我中文提示
  18. 百度地图爬虫——小试牛刀
  19. 什么是IO流?怎样区分不同种类的IO流?
  20. 最大信息系数(MIC)

热门文章

  1. 正交试验法生成测试用例工具PICT的使用
  2. Java静态方法调用内部类
  3. linux cpu监控
  4. CSDN为什么没有单独购买积分的方式?
  5. 杭电oj —— 2058 (超时优化)
  6. 从网页搭建入门python web_从网页搭建入门JavaWeb
  7. linux 启动redis服务
  8. 基于html扫雷游戏毕业论文,扫雷游戏的设计与开发毕业设计毕业论文正稿
  9. 大学情侣毕业卖卤肉,做出了自己的品牌
  10. 解决分布式事务,Seata真香