C语言中select函数的使用
一般用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函数的使用相关推荐
- C语言中select函数简介及使用
select函数用来检查套接字描述符(sockets descriptors)是否已准备好读/写,提供了一种同时检查多个套接字的方法. Linux中select函数的声明在/usr/include/x ...
- 关于C语言中printf函数“输出歧视”的问题
目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...
- C语言中atoi()函数的用法
C语言中atoi()函数的用法 一.学习要点: 1.int atoi(const char *str)把参数str所指向的字符串转换为一个整数: 二.代码 #include<stdio.h> ...
- r语言中c函数错误,R语言中c()函数与paste()函数的区别说明
c()函数:将括号中的元素连接起来,并不创建向量 paste()函数:连接括号中的元素 例如 c(1, 2:4),结果为1 2 3 4 paste(1, 2:4),结果为"1 2" ...
- C语言中main函数的研究,以及对代码断点调试的研究(王爽老师 汇编语言)
版权声明:本文为博主原创文章,未经博主允许不得转载. 我们知道作为一个语言本身是不会有诸如从main函数开始运行这样的条件(深层次的说 底层汇编代码不会指定从mian函数开始的这样的条件,程序开始的位 ...
- 浅析C语言中strtol()函数与strtoul()函数的用法
这篇文章主要介绍了浅析C语言中strtol()函数与strtoul()函数的用法,注意其将字符串转换成long型的区别,需要的朋友可以参考下 头文件: ? 1 #include <stdlib. ...
- c语言memcopy_C语言中memcpy 函数的用法详解
C语言中memcpy 函数的用法详解 memcpy(内存拷贝函数) c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址 ...
- c语言中memcpy函数_带有示例的C中的memcpy()函数
c语言中memcpy函数 memcpy()函数 (memcpy() function) memcpy() is a library function, which is declared in the ...
- c语言中 调用函数除函数名外,【单选题】在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分)
A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值...
[单选题]在 C 语言中 , 调用函数除函数名外 , 还必须有 ( ). (10.0分) A. 函数预说明 B. 实际参数 C. ( ) D. 函数返回值 更多相关问题 下列关于IMOECDIS性能标 ...
最新文章
- Genome Research | TransBorrow:通过借用不同拼接工具的拼接结果来引导完成转录组拼接
- centos telnet 安装 配置
- Atitit usrQBK1600 技术文档的规范标准化解决方案
- SecureCRT 全屏切换
- 秒懂系列 | 史上最简单的Python Django入门教程
- JAVA类定义,成员类,抽象类及接口类
- 使用jquery datatables插件遇到fnReloadAjax的问题
- mockito 外部接口_mockito – Spring批处理作业的端到端测试用例
- 前端基础语言HTML、CSS 和 JavaScript 学习指南
- 读取 system serial number
- 几个很实用的软件 root 改机 软改 硬改 改串号 改设备 参数生成器APK 电脑软件
- ModifyStyle, ModifyStyleEx
- 【解决方法】Socket服务端退出之后端口依旧被占用
- 【知识兔】Ctrl+H,Word文档中超好用的快捷键
- SharpDevelop安装与配置
- uniapp app安卓系统真机调试
- windows输入法第一次输入的时候有时候不给我中文提示
- 百度地图爬虫——小试牛刀
- 什么是IO流?怎样区分不同种类的IO流?
- 最大信息系数(MIC)