前言

在看过前文:初探IO复用后,想必你已对IO复用这个概念有了初步但清晰的认识。

接下来,我要在一个具体的并发客户端中实现它(基于select函数),使得一旦服务器中的客户进程被终止的时候,客户端这边立即得到通知并返回异常。

select函数

函数原型:int select ( int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout )

包含头文件:sys/select.h  sys/time.h ( 两个都要包含 )

参数说明:maxfdp1表示监听描述符个数( 一般直接赋予最大描述符号的值+1 ),中间几个参数表示具体的监听描述符集( 读/写/异常描述符集,本质是位向量组 ),最后一个参数表示监听的时间限制结构体。

配套使用宏:

1. void FD_ZERO ( fd_set *fdset ) 监听描述符集清零

2. void FD_SET ( int fd, fd_set *fset ) 注册要监听的描述符

3. void FD_CLR ( int fd, fd_set *fdset ) 注销不要监听的描述符

4. int FD_ISSET ( int fd, fd_set *fdset ) 判断某个监听信号是否接收到( 一般用于在select函数调用后某个信号是否接收到判断 )

返回值:返回已经就绪的描述符的个数,如果是定时器到时则返回0,出错则返回-1。

大致用法:

1. 定义一个空的描述符集

以下部分循环:

2. 注册要监听的描述符

3. 调用select函数

4. 依次编写IO处理代码( 一般是if ( FD_ISSET(描述符), &监听描述符集 ) { } 这样的结构 )。

代码实现

下面的代码对之前的客户端代码做了修改,增加了基于select函数的IO复用机制:

 #include    "unp.h"

 void
str_cli(FILE *fp, int sockfd)
{
int maxfdp1;
// 定义描述符集
fd_set rset;
char sendline[MAXLINE], recvline[MAXLINE]; // 清空描述符集
FD_ZERO(&rset);
for ( ; ; ) {
// 注册要监听的两个描述符
FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
// 计算最大描述符并将它+1后作为select函数的第一个参数
maxfdp1 = max(fileno(fp), sockfd) + ;
// 调用并阻塞于select函数
Select(maxfdp1, &rset, NULL, NULL, NULL); // 读取回射以及处理TCP分节
if (FD_ISSET(sockfd, &rset)) {
if (Readline(sockfd, recvline, MAXLINE) == )
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);
} // 处理用户输入
if (FD_ISSET(fileno(fp), &rset)) {
if (Fgets(sendline, MAXLINE, fp) == NULL)
return;
Writen(sockfd, sendline, strlen(sendline));
}
}
}

运行测试

经过测试,发现当服务器杀死客户端子进程后,客户端这边立刻报错并退出了程序。

第十七篇:IO复用之select实现的更多相关文章

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

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

  2. IO复用之select实现

    前言 在看过前文:初探IO复用后,想必你已对IO复用这个概念有了初步但清晰的认识.接下来,我要在一个具体的并发客户端中实现它( 基于select函数 ),使得一旦服务器中的客户进程被终止的时候,客户端 ...

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

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

  4. IO复用: select 和poll 到epoll

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

  5. 网络编程之IO复用:select or epoll

    对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接上的报文,与此同时,可能服务器上还有数以十万计的最近几秒没有收发任何报文的相对不活跃连接.同时处理 ...

  6. 多路IO复用模型--select, poll, epoll

    select 1.select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024,单纯改变进程打开的文件描述符个数并不能改变select监听文件个数 2.解决1024以下客户端时使用se ...

  7. 6. IO复用:select 和 poll

    select #include <sys/select.h> #include <sys/time.h> int select(int maxfdp1, fd_set *rea ...

  8. IO复用与select函数

    socket select函数的详细讲解 select函数详细用法解析      http://blog.chinaunix.net/uid-21411227-id-1826874.html linu ...

  9. 第十六篇:初探IO复用

    前言 在之前的文章中,我具体实现了一个并发回射服务器并给它加载了僵尸子进程的自动清理信号机制.在正常情况下,它已经可以很好地工作了,但它能否合理应对一些特殊情况呢? 问题发现 先来看看当服务器的客户子 ...

随机推荐

  1. 图的基本算法(BFS和DFS)

    图是一种灵活的数据结构,一般作为一种模型用来定义对象之间的关系或联系.对象由顶点(V)表示,而对象之间的关系或者关联则通过图的边(E)来表示. 图可以分为有向图和无向图,一般用G=(V,E)来表示图. ...

  2. 树莓派3 U盘启动 配置 & 即 MSD启动 总结

    树莓派3添加了一个新特性:允许USB启动.现在我们既可以从SD卡启动,也可以从USB启动.USB设备可以是U盘,带USB适配器的SSD硬盘,甚至是移动硬盘. 本文介绍怎么从U盘启动树莓派3.   1. ...

  3. I2C上拉电阻

    在一些PCB的layout中,大家往往会看到在I2C通信的接口处,往往会接入一个4.7K的电阻,有的datasheet上面明确有要求,需要接入,有的则没有要求.   I2C接口 对于单片机来讲,有些I ...

  4. 关于Unity中协程、多线程、线程锁、www网络类的使用

    协程 我们要下载一张图片,加载一个资源,这个时候一定不是一下子就加载好的,或者说我们不一定要等它下载好了才进行其他操作,如果那样的话我就就卡在了下载图片那个地方,傻住了.我们希望我们只要一启动加载的命 ...

  5. 关于Unity中地形的创建

    地形创建 Raw图片格式是Unity可以导出的图片格式 Unity很强大,可以直接使用psd文件 地形创建实例 1.创建Unity工程和文件目录1:创建一个地形Terrain: GameObject- ...

  6. SQLSERVER中统计所有表的记录数

    SQLSERVER中统计所有表的记录数 利用系统索引表sysindexes中索引ID indid<1的行中的rows列存有该表的行数这一特点.    方法是利用隐藏未公开的系统存储过程sp_MS ...

  7. Linux系统中如何校验SHA1和MD5?

    来自:系统之家:http://www.xitongzhijia.net/xtjc/20160316/69125.html 我们在网络上下载或在U盘中复制的文件正常来说和源文件是一样的,但有时在下载或拷 ...

  8. Linux命令_磁盘管理_查看磁盘或目录的容量

    软件环境:虚拟机VM12,Linux版本 CentOS 7.3 命令 df (disk filesystem) 用于查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认以KB为单位显示 ...

  9. vector 用法小例子

    1. vector<int> vec; vec.push_back(1); 2. vector<int> vec(10); vec[0] = 1;

  10. Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)

    一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...