前言

  在看过前文:初探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复用机制:

  1. #include "unp.h"
  2.  
  3. void
  4. str_cli(FILE *fp, int sockfd)
  5. {
  6. int maxfdp1;
  7. // 定义描述符集
  8. fd_set rset;
  9. char sendline[MAXLINE], recvline[MAXLINE];
  10.  
  11. // 清空描述符集
  12. FD_ZERO(&rset);
  13. for ( ; ; ) {
  14. // 注册要监听的两个描述符
  15. FD_SET(fileno(fp), &rset);
  16. FD_SET(sockfd, &rset);
  17. // 计算最大描述符并将它+1后作为select函数的第一个参数
  18. maxfdp1 = max(fileno(fp), sockfd) + ;
  19. // 调用并阻塞于select函数
  20. Select(maxfdp1, &rset, NULL, NULL, NULL);
  21.  
  22. // 读取回射以及处理TCP分节
  23. if (FD_ISSET(sockfd, &rset)) {
  24. if (Readline(sockfd, recvline, MAXLINE) == )
  25. err_quit("str_cli: server terminated prematurely");
  26. Fputs(recvline, stdout);
  27. }
  28.  
  29. // 处理用户输入
  30. if (FD_ISSET(fileno(fp), &rset)) {
  31. if (Fgets(sendline, MAXLINE, fp) == NULL)
  32. return;
  33. Writen(sockfd, sendline, strlen(sendline));
  34. }
  35. }
  36. }

运行测试

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

IO复用之select实现的更多相关文章

  1. 第十七篇:IO复用之select实现

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

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

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

  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, poll, epoll

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

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

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

  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复用(较详细)

    进程与线程的描述 一个进程至少会创建一个线程,多个线程共享一个程序进程的内存.程序的运行最终是靠线程来完成操作的.线程的数量跟CPU核数有关,一个核最多能发出两个线程.线程的操作主要分为:一:给CPU ...

随机推荐

  1. iOS-sqlite3&FMDB使用代码示范

    数据库操作是我们使用十分频繁的一份操作,在iOS中如何使用数据库,使用什么数据库,是我们不得不考虑的一个问题. 小型数据我们可以使用plist文件,或者NSUserDefaults存储.数据量比较多得 ...

  2. 洛谷 P 1133 教主的花园

    题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值. 教主最喜欢3种树,这3种树 ...

  3. 我的logging 配置

    #encoding=utf-8 import logging.config logging.config.dictConfig({ 'version': 1, 'disable_existing_lo ...

  4. Linux 之 Vim常用命令

    Vim常用命令 参考教程:[千峰教育] 终端编辑命令工具: vi/vim.emacs等. vim简介: vim是vi的扩展,被誉为终端编辑之神. vim安装: yum install -y vim 工 ...

  5. LeetCode OJ--Longest Consecutive Sequence ***

    http://oj.leetcode.com/problems/longest-consecutive-sequence/ 起初想的是排序,查了下O(n)的排序算法有计数排序.基数排序.桶排序.后来考 ...

  6. DB2数据库 CASE WHEN的使用

    THEN T1.INSURANCEMATURITYDATE ELSE T1.COMMERCIALENDDATE END as m, T1.INSURANCEMATURITYDATE ,T1.COMME ...

  7. socket的accept: Invalid argument问题

    void local_sdk_server::wait_remote_client_connect_and_comm() { /*服务器服务启动,等待客户端的链接的到来*/ //sockaddr_in ...

  8. 访问权限修饰符Protected专题

    上图描述:A类在a包下,m()方法被protected修饰 上图描述:B类也在a包下,B类是A类的子类. 解析:B类和A类是同包类,B类是A类的子类,因此b对象可以调用m()方法. 上图描述:C类也在 ...

  9. 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”

    首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中对本模块提供给其它模块 ...

  10. 编写Web Serviceclient訪问www.webxml.com.cn提供的服务

    好久没更新博客了,近期各种忙. 之前做Web Service课程的作业,当中有一个实验.实验内容如题所看到的. 以下简单说下怎样编写Web Serviceclient訪问webxml.com.cn里的 ...