Linux 网络编程(IO模型)
针对linux 操作系统的5类IO模型,阻塞式、非阻塞式、多路复用、信号驱动和异步IO进行整理,参考《linux网络编程》及相关网络资料。
阻塞模式
在socket编程(如下图)中调用如下四类函数导致阻塞:
- 读操作(read、readv、recv、recvfrom、recvmsg):当应用程序调用读函数,该系统调用进入内核态,若套接字接收缓冲区无数据则阻塞,数据到达则将接收缓冲区数据拷贝至进程缓冲区并返回。对TCP而言,一旦接收缓冲区中与数据则进程被唤醒,对UDP而言有完整的UDP报文达到进程被唤醒。
- 写操作(write、writev、send、sendto、sendmsg):当发送缓冲区空间小于写操作要求写的数量则阻塞,该情况发生很少。对UDP而言,不存在发送缓冲区,因此不可能发送阻塞。
- 接收连接(accept):TCP协议采用倾听套接字接收客户机连接请求,完成三次握手的TCP连接保存在倾听套接字完成队列。当accept被调用时,若完成队列为空则阻塞。当有新的TCP连接,进程被唤醒同时分配一个新的连接套接字标识这个TCP连接。
- 建立连接(connect):TCP套接字调用connect与服务器连接时进程将阻塞,待3次握手操作完成后(内核态)进程被唤醒。

非阻塞模式
针对上述四类阻塞模式的socket调用,均可通过设置的方式使其非阻塞。设置方式有两种fcntl设置套接字为O_NONBLOCK,以及ioctl设置FIONBIO。完成后其四类操作非阻塞,如下:
- 读操作:缓冲区无数据,函数以错误EWOULDBLOCK返回;
- 写操作:发送缓冲区无空间,函数以错误EWOULDBLOCK返回;
- 接收连接:若队列中无新的连接,函数以错误EWOULDBLOCK返回;
- 连接操作:若连接不能马上建立,返回错误类型EINPROGRESS;
非阻塞模式在运用中采用轮询,或配合select的方式使用。
多路复用
进程定义读描述符集、写描述符集以及异常描述符集(作为select的入参),在select被调用时如果没有描述符集就绪,该select将被阻塞。当有任何一个或几个描述符就绪时,select设置描述符集,并返回就绪描述符的个数。
/*
* 多路复用select函数,参数定义如下
* nfds: select监视的文件句柄数,一般设置为最大文件号+1
* readfds:select监视的可读文件句柄集合
* writefds:select监视的可写文件句柄集合
* exceptfds:select监视的异常文件句柄集合
*/
int select(nfds, readfds, writefds, exceptfds, timeout)
注:对于监视一个描述符的情况,select与阻塞模式无区别。
信号驱动
信号驱动的方式属于一种异步的IO方式,进程本身不会被挂起,流程如下:

信号驱动的IO方式主要分以下三步操作:
signal(SIGIO,sig_handler); //设置SIGIO信号对应的处理函数
fcntl(sockfd,F_SETOWN, getpid());//设置接收SIGIO信号的进程为当前进程,该信号由sockfd句柄产生
ioctl(sockfd,FIOASYNC,&on);//允许sockfd套接字进行信号驱动的输入输出
对于UDP套接字,内核在以下情况下发送信号SIGIO:
- 套接字上接收到一个UDP数据报
- 套接字上发生一个异步错误
对TCP套接字,内核在以下情况下发送信号SIGIO:
- 在倾听套接字上,一个连接请求完成
- 初始化了一个断开连接的请求
- 断开连接请求完成
- 一个方向的连接被关闭
- 数据到达套接字
- 套接字发送了数据
- 异步错误发生
异步IO
异步IO是linux 2.6内核的标准特性,基本思想是允许进程发起很多IO操作,而不用阻塞或等待任何操作。稍后在接收到IO操作完成的通知时,再检索IO操作的结果。
aio过程的数据缓存在结构体aiocb中,该结构体定义如下:
struct aiocb
{
int aio_fildes; /* File desriptor. */ int aio_lio_opcode; /* Operation to be performed. */int aio_reqprio; /* Request priority offset. */ volatile void *aio_buf; /* Location of buffer. */
size_t aio_nbytes; /* Length of transfer. */struct sigevent aio_sigevent; /* Signal number and value. */
根据posix.1b所要求,主要包括如下函数:
- aio_read(struct aiocb* aiocbp); //进行异步读操作
- aio_write(struct aiocb* aiocbp);//进行异步写操作
- aio_error(struct aiocb* aiocbp);//确定请求的状态
- aio_return(struct aiodb* aiocbp);//读写的异步返回
Linux 网络编程(IO模型)的更多相关文章
- linux网络编程IO模型
同步与异步: 同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成. 异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要 ...
- Linux网络编程-IO复用技术
IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...
- LINUX网络编程 IO 复用
参考<linux高性能服务器编程> LINUX下处理多个连接时候,仅仅使用多线程和原始socket函数,效率十分低下 于是就出现了selelct poll epoll等IO复用函数. 这 ...
- linux网络编程 IO多路复用 select epoll
本文以我的小型聊天室为例,对于服务器端的代码,做了三次改进,我将分别介绍阻塞式IO,select,epoll . 一:阻塞式IO 对于聊天室这种程序,我们最容易想到的是在服务器端accept之后,然后 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- Linux 网络编程的5种IO模型:信号驱动IO模型
Linux 网络编程的5种IO模型:信号驱动IO模型 背景 上一讲 Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 我们讲解了多路复用等方面的知识,以及有关例程. ...
- Linux 网络编程的5种IO模型:异步IO模型
Linux 网络编程的5种IO模型:异步IO模型 资料已经整理好,但是还有未竟之业:复习多路复用epoll 阅读例程, 异步IO 函数实现 背景 上一讲< Linux 网络编程的5种IO模型:信 ...
- linux网络编程模型
1.编程模型 Linux网络编程模型是基于socket的编程模型
- Linux网络编程(四)
在linux网络编程[1-3]中,我们编写的网络程序仅仅是为了了解网络编程的基本步骤,实际应用当中的网络程序并不会用那样的.首先,如果服务器需要处理高并发访问,通常不会使用linux网络编程(三)中那 ...
随机推荐
- 《VB语言程序设计(第3版)》总结
我之前因学习昆仑通态的组态软件MCGS,用并学习过VB,还买了一本书<VB语言程序设计(第3版)>.现在在某公司实习,最近接触老的项目,又要用到VB.我就又把那本书大体看了一遍,并对其进行 ...
- Java 验证码、二维码
Java 验证码.二维码 资源 需要: jelly-core-1.7.0.GA.jar网站: http://lychie.github.io/products.html将下载下来的 jelly ...
- [erlang]supervisor(监控树)的重启策略
1. init函数 init() -> {ok, {SupFlags, [ChildSpec,...]}} | ignore. [ChildSpec,...] 是在init之后默认要启动的子进程 ...
- php二维数组按照键值排序的方法
//按照传入数组中的num倒序 public function numdesc($array,$key="num",$order="desc"){ $arr_n ...
- css 3 动画
1.transition,其作用是:平滑的改变CSS的值.无论是点击事件,焦点事件,还是鼠标hover,只要值改变了,就是平滑的,就是动画. transition 属性介绍: transition-p ...
- HTML页面跳转的5种方法
下面列了五个例子来详细说明,这几个例子的主要功能是:在5秒后,自动跳转到同目录下的hello.html(根据自己需要自行修改)文件.1) html的实现 <head> <!-- 以下 ...
- viewpage滑动查看图片并再有缩略图预览
首先看下效果图, 主要功能分为3大块 一是滑动查看,通过viewpage来实现,方法见 http://www.cnblogs.com/lovemo1314/p/6109312.html 二.点击放大 ...
- Android中Handler 、Thread和Runnable之间的关系
在多线程编程的时候,我们经常会用到Handler,Thread和Runnable这三个类,我们来看看这三个类之间是怎么样的关系? 首先说明Android的CPU分配的最小单元是线程,Handler一般 ...
- Learning ROS for Robotics Programming - Second Edition(《学习ROS机器人编程-第二版》)
Learning ROS for Robotics Programming - Second Edition <学习ROS机器人编程-第二版> ----Your one-stop guid ...
- jQqery EasyUI dategrid行中多列数据的可编辑操作
最近的项目中需要在前台dategrid列表中直接修改某些列的数据,并且修改后的数据需要不通过后台而自动更新在列表中. 带着这一问题开始寻找实现的思路,首先想到的就是去jQqery EasyUI官网找例 ...