IO复用:

I/O复用使得程序可以同时监听多个文件描述符,这对提高程序的性能至关重要。例如TCP服务器要同时处理监听socket和连接socket,客户端要同时处理用户输入和网络连接.

Linux下实现I/O复用的系统调用主要有select、poll和epoll.

select函数:

#include <sys/select.h>
int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* excepefds,struct timeval* timeout);

函数参数介绍:

(1)nfds:指定被监听的文件描述符的总数.它通常被设置为select监听的所有的文件描述中的最大值加1.因为文件描述符是从0开始的.

(2)readfds、writefd和exceptfds参数:指向可读、可写和异常等事件对应的文件描述符集合.select调用返回时,内核将修改它们来通知应用程序哪些文件描述符已经就绪.(fd_set结构体仅包含一个整型数组,该数组的每个元素的每一位(bit)都标记一个文件描述符.fd_set能够容纳的文件描述符数量是由FD_SETSIZE来指定,这就限制了select能同时处理的文件描述符的总量).

因为位操作比较繁琐,所以使用下列宏来实现:

FD_ZERO(fd_set *fdset); //清除fdset的所有位

FD_SET(int fd,fd_set *fdset);  //设置fdset的位

FD_CLR(int fd,fd_set *fd_set);  //清除fdset的位fd

int FD_ISSET(int fd,fd_set *fd_set);//判断fdset的位fd是否被设置

(3)timeout参数:被用来设置select函数的超时时间.使用指针参数是因为内核将修改它以告诉用户select等了多久.

struct timeval结构体定义:

struct timeval{
long tv_sec;/*秒数*/
long tv_usec; /*微秒*/
};
  • timeout变量的tv_sec和tv_usec成员都被设为0,则select将立即返回.
  • timeout=NULL:select将一直阻塞,直到某个文件描述符就绪.

返回值:>0  成功时返回就绪(可读、可写和异常)文件描述符的总数.

=0   在超时时间内没有任何文件描述符就绪.

=-1    失败时,同时并设置errno.

例子:利用select接受普通数据和带外数据都将使select返回.但socket处于不同的就绪状态:前者处于可读状态,后者处于异常状态.

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h> int main(int argc,const char* argv[]){
if(argc<=){
printf("usage:%s ip port\n",argv[]);
return -;
} const char* ip=argv[];
int port=atoi(argv[]); struct sockaddr_in address;
address.sin_family=AF_INET;
inet_pton(AF_INET,ip,&address.sin_addr);
address.sin_port=htons(port); int sockfd=socket(AF_INET,SOCK_STREAM,);
assert(sockfd!=-); int ret=bind(sockfd,(struct sockaddr*)&address,sizeof(address));
assert(ret!=-); ret=listen(sockfd,);
assert(ret!=-); struct sockaddr_in client_address;
socklen_t len=sizeof(client_address);
int connfd=accept(listenfd,(struct sockaddr*)&client_address,&len);
assert(connfd>=); fd_set readSet;
fd_set exceptionSet;
FD_ZERO(&readSet);
FD_ZERO(&exceptionSet);
char buf[]; while(){
memset(buf,'\0',); FD_SET(connfd,&readSet);
FD_SET(connfd,&exceptionSet); ret=select(connfd+,&readSet,NULL,&exceptionSet,NULL);
if(ret<){
printf("select error\n");
break;
} if(FD_ISSET(connfd,&readSet)){
ret=recv(connfd,buf,sizeof(buf),);
if(ret<=){
break;
} printf("recv data:%s and length:%d\n",buf,ret);
} else if(FD_ISSET(connfd,&exceptionSet)){
ret=recv(connfd,buf,sizeof(buf),MSG_OOB);
if(ret<=){
break;
} printf("recv oob data:%s and length:%d\n",buf,ret);
}
} close(connfd);
close(sockfd);
return ;
}

I/O复用-select模型的更多相关文章

  1. select模型的原理、优点、缺点

    关于I/O多路复用: I/O多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一 个通知.这样当配合非阻塞的socket ...

  2. I/O复用----select

    2018-07-31 (星期二)I/O复用:    一个应用程序通常需要服务一个以上的文件描述符.    例如stdin,stdout,进程间通信以及若干文件进行I/O,如果不借助线程的话,(线程通常 ...

  3. Socket I/O模型之select模型

    socket网络编程中有多种常见的I/O模型: 1.blocking阻塞 2.nonblocking非阻塞 3.I/O multiplexing复用 4.signal driven 5.asynchr ...

  4. I/O复用select 使用简介

    一:五种I/O模型区分: 1.阻塞I/O模型      最流行的I/O模型是阻塞I/O模型,缺省情形下,所有套接口都是阻塞的.我们以数据报套接口为例来讲解此模型(我们使用UDP而不是TCP作为例子的原 ...

  5. 一只简单的网络爬虫(基于linux C/C++)————浅谈并发(IO复用)模型

    Linux常用的并发模型 Linux 下设计并发网络程序,有典型的 Apache 模型( Process Per Connection ,简称 PPC ), TPC ( Thread Per Conn ...

  6. 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记.

    说明 为何要写这篇文章 ,之前看过阿二的梦想船的<Poco::TCPServer框架解析> http://www.cppblog.com/richbirdandy/archive/2010 ...

  7. windows socket编程select模型使用

    int select(         int nfds,            //忽略         fd_ser* readfds,    //指向一个套接字集合,用来检测其可读性       ...

  8. socket编程的select模型

    在掌握了socket相关的一些函数后,套接字编程还是比较简单的,日常工作中碰到很多的问题就是客户端/服务器模型中,如何让服务端在同一时间高效的处理多个客户端的连接,我们的处理办法可能会是在服务端不停的 ...

  9. linux下多路复用模型之Select模型

    Linux关于并发网络分为Apache模型(Process per Connection (进程连接) ) 和TPC , 还有select模型,以及poll模型(一般是Epoll模型) Select模 ...

随机推荐

  1. For循环复杂练习

    for是循环当中经常用到的一个结构,练熟了才可以. 练习-需求描述: 在控制台打印以下形式的字符: * * * * * * * * * * * * * * * 思路,首先分析需求的规律 1.首先分析需 ...

  2. yum命令常见方法

    yum check-update 检查可更新的所有软件包 yum update 下载更新系统已安装的所有软件包 yum upgrade 大规模的版本升级,与yum update不同的是,连旧的淘汰的包 ...

  3. Linux kernel ‘fib6_add_rt2node’函数安全漏洞

    漏洞名称: Linux kernel ‘fib6_add_rt2node’函数安全漏洞 CNNVD编号: CNNVD-201307-265 发布时间: 2013-07-16 更新时间: 2013-07 ...

  4. Linux Shell编程(4)——shell特殊字符(上)

    在脚本或其他别的地方出现的特殊字符#注释. 以一个#开头的行 (#!是例外) 是注释行.# 这是一行注释.注释也可以出现在一个命令语句的后面.echo "A comment will fol ...

  5. 字符串[未AC](后缀自动机):HEOI 2016 str

    超级恶心,先后用set维护right,再用主席树维护,全部超时,本地测是AC的.放心,BZOJ上还是1S限制,貌似只有常数优化到一定境界的人才能AC吧. 总之我是精神胜利了哦耶QAQ #include ...

  6. svn server安装配置

    安装平台:RHEL5 1.安装软件:httpd.subversion.mod_dav_svn 2.修改配置 修改/etc/httpd/conf.d/subversion.conf.eg: LoadMo ...

  7. web前端开发中Nodejs、Grunt、npm等的介绍、使用

    一.Nodejs的安装: Grunt和所有grunt插件都是基于nodejs来运行的,如果你的电脑上没有nodejs,就去安装吧.去 https://nodejs.org/ 上,点击页面中那个绿色.大 ...

  8. 使用 HTMLTestRunner.py

    HTMLTestRunner.py python 2版本 下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html 教程:http://www. ...

  9. Linux 相关scsi命令

    Linux 相关scsi命令 由于前段时间存储扩容,对存储操作较多,下面记录了常用的操作: lsscsi命令:显示scsi设备信息 #lsscsi [0:0:0:2]    disk    IBM   ...

  10. Freemarker数字转时间

    使用freemarker模板,展示一个时间字段,数据库保存的是毫秒.在网上找了许多文章,发现都是针对date或者是直接类似"1999-09-09"这样已经成型字符串进行操作的,心中 ...