IO复用——select系统调用
1、select函数
此函数用于在一段时间内,监听用户感兴趣的文件描述符上的可读、可写和异常等事件。
#include<sys/select.h>
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout)
- nfds参数指示被监听的文件描述符总数。通常设置为最大文件描述符值+1,因为文件描述符从0开始计数
- readfds、writefds和exceptfds参数分别指可读、可写和异常事件对应的文件描述符集合。函数返回时,内核将修改它们来通知应用程序已经就绪的文件描述符。在下次调用select之前,需要重新设置文件描述符。
- timeout参数指定超时时间。使用指针,内核可以通过修改此值来告诉应用程序函数等待的时间,但是调用失败时,此值不确定。如果传入结构内的成员都为0,则函数立即返回;如果传入NULL,则函数一直阻塞,直到有文件描述符就绪。
- 函数成功返回时,返回就绪的文件描述总数;超时时间内没有文件描述符就绪,就返回0;失败返回-1并设置errno;如果在函数等待期间,程序接收到信号,则select立即返回-1,并置errno为EINTR。
fd_set结构体中是一个整型数组,该数组中的每一个元素的每一位标识一个文件描述符。fd_set能容纳的文件描述符数量由FD_SETSIZE指定。使用下列宏来访问fd_set结构体中的位:
FD_ZERO(fd_set* fdset) //清除fdset的所有位
FD_SET(int fd, fd_set* fdset) //设置fdset的fd位
FD_CLR(int fd, fd_set* fdset) //清除fdset的fd位
int FD_ISSET(int fd, fd_set* fdset) //检测fdset的位fd是否被置位
struct timeval结构定义如下:
struct timeval
{
long tv_sec; //秒数
long tv_usec; //微秒数
}
2、网络编程中文件描述符就绪条件
可读:
- socket内核接收缓冲区中的字节数大于或等于其低水位标记SO_RCVLOWAT,此时可无阻塞的读socket,读操作返回值大于0
- socket通信对方关闭连接,此时读该socket将返回0
- 监听socket上有新的连接请求
- socket上有未处理的错误,此时可调用getsockopt来读取和清除错误
可写:
- socket内核发送缓冲区中的可用字节数大于或等于其低水位标记SO_SNDLOWAT,此时可无阻塞的写socket,写操作返回值大于0
- socket的写操作被关闭,对写操作被关闭的socket执行写操作将触发一个SIGPIPE信号
- socket使用非阻塞connect连接成功或者失败(超时)之后
- socket上有未处理的错误,此时可调用getsockopt来读取和清除错误
3、select异常处理
select能处理的异常只有一种,即socket上接收到带外数据。带外数据的处理可参见下面的程序示例。
4、程序示例
void worker(int connfd) //参数为与客户侧连接的socket
{
char buf[1024];
fd_set read_fds;
fd_set exception_fds;
FD_ZERO(&read_fds);
FD_ZERO(&exception_fds);
while(1)
{
memset(buf, 0, sizeof(buf));
FD_SET(connfd, &read_fds);
FD_SET(connfd, &exception_fds);
ret = select(connfd + 1, &read_fds, NULL, &exception_fds, NULL);
if(ret < 0)
{
printf("select fail\n");
break;
}
if(FD_ISSET(connfd, &read_fds))
{
ret = recv(connfd, buf, sizeof(buf)-1, 0);
if(ret <= 0)
{
break;
}
//处理数据代码
}
//对于异常事件,采用带MSG_OOB标志的recv函数来读取带外数据
else if(FD_ISSET(connfd, &exception_fds))
{
ret = recv(connfd, buf, sizeof(buf)-1, MSG_OOB);
if(ret <= 0)
{
break;
}
//处理带外数据代码
}
}
close(connfd);
return;
}
IO复用——select系统调用的更多相关文章
- io复用select方法编写的服务器
摘要:io多路复用是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般都是读就绪或者写就绪),就能通知应用程序进行相应的读写操作.select函数作为io多路复用的机制,第一个参数nfds是f ...
- IO复用——poll系统调用
1.poll函数 #include<poll.h> int poll(struct pollfd* fds, nfds_t ndfs, int timeout) poll函数在一定的时间内 ...
- IO复用: select 和poll 到epoll
linux 提供了select.poll和epoll三种接口来实现多路IO复用.下面总结下这三种接口. select 该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经 ...
- select、poll、epoll三组IO复用
int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout)//其中n ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- 【Unix网络编程】chapter6 IO复用:select和poll函数
chapter6 6.1 概述 I/O复用典型使用在下列网络应用场合. (1):当客户处理多个描述符时,必须使用IO复用 (2):一个客户同时处理多个套接字是可能的,不过不叫少见. (3):如果一个T ...
- linux的IO复用,select机制理解--ongoing
一:首先需要搞清楚IO复用.阻塞的概念: Ref: https://blog.csdn.net/u010366748/article/details/50944516 二:select机制 作为IO ...
- Select、Poll、Epoll IO复用技术
简介 目前多进程方式实现的服务器端,一次创建多个工作子进程来给客户端提供服务, 但是创建进程会耗费大量资源,导致系统资源不足 IO复用技术就是让一个进程同时为多个客户端端提供服务 IO复用技术 之 S ...
- 使用select io复用实现超时设置
在linux的socket编程中,经常会遇到超时设置的问题,例如请求方如果在Ks内不发送数据则服务器要断开连接停止服务.这里我使用select的io复用实现超时5s设置,具体代码片段如下: fd_se ...
随机推荐
- day012-Lambda、方法引用
1. 函数式接口 有且只有一个抽象方法的接口就是函数式接口. 函数式接口的定义格式: Interface 接口名{ 抽象方法: } @Override:用来修饰方法声明,告诉编译器该方法是重写父类的方 ...
- ORACLE_LPAD_FUNCTION
Oracle / PLSQL: LPAD Function This Oracle tutorial explains how to use the Oracle/PLSQL LPAD functio ...
- 【java开发系列】—— 嵌套类与内部类
嵌套类与内部类在java中使用的很广泛,为了避免难以理解,这里用了几个小例子,说明它的用法. 嵌套类与内部类的结构如下图 静态嵌套类 静态嵌套类,是一种在类之外声明的嵌套类,由于是静态的,所以不经过初 ...
- 免费的SSL证书,你值得拥有!Let's Encrypt 试用体验记录
早上收到 Let’s Encrypt 的邮件,说偶之前申请的已经通过了,于是马上开始试用.Let’s Encrypt 是一个新的数字证书认证机构,它通过自动化的过程消除创建和安装证书的复杂性,为网站提 ...
- 3.GlusterFS 企业分布式存储的搭建
3.1 硬件要求 一般选择 2U 机型,磁盘 SATA 盘 4TB,如果 IO 要求比较高,可以采购 SSD 固态硬盘.为了充分保证系统的稳定性和性能,要求所有 glusterfs 服务器硬件配置尽量 ...
- TCP的建立和关闭
一.TCP头信息 简单的至少应该知道,源端口,目的端口,序号,确认号,标志位,校验和 二.TCP的建立 1.客户端将SYN标志位置1,同时生成随机的序号,确认号是0. 2.服务器接收到SYN,知道有人 ...
- 20165322 2017-2018-2《Java程序设计》课程总结
20165322 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:我期望的师生关系 预备作业2:做中学learning by doing个人感想 预备作业 ...
- 2018.12.1 web项目中解决乱码问题的一个工具类
<!-- 配置一个过滤器 编码格式的过滤器 --> <filter> <filter-name>encodeFilter</filter-name> & ...
- 【洛谷P2657】[SCOI2009] windy数
最近学习了一下数位DP 感觉记忆化搜索是比较好理解的 这篇博客对我有一定的启发https://www.cnblogs.com/zbtrs/p/6106783.html 总结了一下: 用数位DP的 ...
- Android UI开发专题(转)
http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255 Android UI开发专题(一) 之界面设计 近期 ...