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系统调用的更多相关文章

  1. io复用select方法编写的服务器

    摘要:io多路复用是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般都是读就绪或者写就绪),就能通知应用程序进行相应的读写操作.select函数作为io多路复用的机制,第一个参数nfds是f ...

  2. IO复用——poll系统调用

    1.poll函数 #include<poll.h> int poll(struct pollfd* fds, nfds_t ndfs, int timeout) poll函数在一定的时间内 ...

  3. IO复用: select 和poll 到epoll

    linux 提供了select.poll和epoll三种接口来实现多路IO复用.下面总结下这三种接口. select 该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经 ...

  4. select、poll、epoll三组IO复用

    int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout)//其中n ...

  5. linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

      IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...

  6. 【Unix网络编程】chapter6 IO复用:select和poll函数

    chapter6 6.1 概述 I/O复用典型使用在下列网络应用场合. (1):当客户处理多个描述符时,必须使用IO复用 (2):一个客户同时处理多个套接字是可能的,不过不叫少见. (3):如果一个T ...

  7. linux的IO复用,select机制理解--ongoing

    一:首先需要搞清楚IO复用.阻塞的概念: Ref:  https://blog.csdn.net/u010366748/article/details/50944516 二:select机制 作为IO ...

  8. Select、Poll、Epoll IO复用技术

    简介 目前多进程方式实现的服务器端,一次创建多个工作子进程来给客户端提供服务, 但是创建进程会耗费大量资源,导致系统资源不足 IO复用技术就是让一个进程同时为多个客户端端提供服务 IO复用技术 之 S ...

  9. 使用select io复用实现超时设置

    在linux的socket编程中,经常会遇到超时设置的问题,例如请求方如果在Ks内不发送数据则服务器要断开连接停止服务.这里我使用select的io复用实现超时5s设置,具体代码片段如下: fd_se ...

随机推荐

  1. day012-Lambda、方法引用

    1. 函数式接口 有且只有一个抽象方法的接口就是函数式接口. 函数式接口的定义格式: Interface 接口名{ 抽象方法: } @Override:用来修饰方法声明,告诉编译器该方法是重写父类的方 ...

  2. ORACLE_LPAD_FUNCTION

    Oracle / PLSQL: LPAD Function This Oracle tutorial explains how to use the Oracle/PLSQL LPAD functio ...

  3. 【java开发系列】—— 嵌套类与内部类

    嵌套类与内部类在java中使用的很广泛,为了避免难以理解,这里用了几个小例子,说明它的用法. 嵌套类与内部类的结构如下图 静态嵌套类 静态嵌套类,是一种在类之外声明的嵌套类,由于是静态的,所以不经过初 ...

  4. 免费的SSL证书,你值得拥有!Let's Encrypt 试用体验记录

    早上收到 Let’s Encrypt 的邮件,说偶之前申请的已经通过了,于是马上开始试用.Let’s Encrypt 是一个新的数字证书认证机构,它通过自动化的过程消除创建和安装证书的复杂性,为网站提 ...

  5. 3.GlusterFS 企业分布式存储的搭建

    3.1 硬件要求 一般选择 2U 机型,磁盘 SATA 盘 4TB,如果 IO 要求比较高,可以采购 SSD 固态硬盘.为了充分保证系统的稳定性和性能,要求所有 glusterfs 服务器硬件配置尽量 ...

  6. TCP的建立和关闭

    一.TCP头信息 简单的至少应该知道,源端口,目的端口,序号,确认号,标志位,校验和 二.TCP的建立 1.客户端将SYN标志位置1,同时生成随机的序号,确认号是0. 2.服务器接收到SYN,知道有人 ...

  7. 20165322 2017-2018-2《Java程序设计》课程总结

    20165322 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:我期望的师生关系 预备作业2:做中学learning by doing个人感想 预备作业 ...

  8. 2018.12.1 web项目中解决乱码问题的一个工具类

    <!-- 配置一个过滤器 编码格式的过滤器 --> <filter> <filter-name>encodeFilter</filter-name> & ...

  9. 【洛谷P2657】[SCOI2009] windy数

    最近学习了一下数位DP 感觉记忆化搜索是比较好理解的 这篇博客对我有一定的启发https://www.cnblogs.com/zbtrs/p/6106783.html 总结了一下:    用数位DP的 ...

  10. Android UI开发专题(转)

    http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255 Android UI开发专题(一) 之界面设计 近期 ...