Linux网络编程学习(十一) ----- 五种I/O模式(第六章)
1、五种I/O模式是哪几个?
阻塞I/O,非阻塞I/O,I/O多路复用,信号驱动I/O(SIGIO),异步I/O
一般来讲程序进行输入操作有两个步骤,一是等待有数据可读,二是将数据从系统内核中拷贝到程序的数据集区。
对于一个套接字的数据操作,第一步就是等待数据从网络上传到本地,当数据包到达时,数据将会从网络层拷贝到内核的缓冲中,第二步就是从内核中将数据拷贝到程序的数据区中。
2、五种阻塞模式简介
1)阻塞I/O模式
套接字建立后默认的模式就是阻塞I/O模式,对于UDP而言,数据就绪的标志比较简单:已经收到了一整个数据报或者没有收到。比如说一个进程调用recvfrom()函数时,数据并有就绪,这个时候,进程将会等待数据就绪,数据到后拷贝到程序数据区,然后正常返回,所以,进程调用recvfrom()到该函数返回这段时间是阻塞的。
2)非阻塞I/O
一个套接字设置为非阻塞时,就相当于告诉内核"当我请求的I/O操作不能马上完成时,你想让我的进程休眠等待的时候,不要这么做,请马上返回一个错误给我"。就是调用recvfrom()时数据未就绪,这时内核立即返回一个错误给进程,所以非阻塞时,需要循环不停测试是否有数据可读,也就是polling,应用程序不停的polling内核来检查I/O操作是否就绪,这将极大浪费CPU资源
3)I/O多路复用
使用I/O多路技术时,调用select()或poll()函数,这时读取数据时先阻塞模式调用select()/poll(),也就是数据未就绪就等待直到数据就绪返回,然后调用recvfrom()函数将数据拷贝到程序缓冲区,和阻塞模式相比,还多调用了一个函数,但是多路复用优势在于select()可以等待多个套接字描述符,只要有一个就绪,select()函数就可以返回。
多路技术使用情况有:
当一个客户端需要同时处理多个文件描述符的输入输出操作的时候(一般来说是标准的输入输出和网络套接字), I/O 多路复用技术将会有机会得到使用
- 当程序需要同时进行多个套接字的操作的时候
如果一个 TCP 服务器程序同时处理正在侦听网络连接的套接字和已经连接好的套接字
- 如果一个服务器程序同时使用 TCP 和UDP 协议
如果一个服务器同时使用多种服务并且每种服务可能使用不同的协议(比如inetd就是这样的)
4)信号驱动I/O模式
内核在文件描述符就绪的时候使用信号来通知进程,这种模式就是信号驱动I/O模式,首先需要允许套接字使用信号驱动I/O,还需要安装一个SIGIO的处理函数。这种模式下,系统调用将会立即返回,程序可以继续做其他事情,在数据就绪的时候发送一个SIGIO信号,这样在信号处理函数中进行I/O操作,有点像中断处理。优势在于等待数据时不会阻塞,程序可以做自己的时期,数据到达时发送SIGIO信号进行通知,很大的灵活性,不必为等待数据进行额外的编码。
信号驱动I/O操作使用前提:
- 一个SIGIO信号的处理函数必须设定
- 套接字拥有者必须被设定,一般使用fcntl函数的F_SETOWN参数来进行设定拥有者
- 套接字必须被允许使用一部I/O,一般用fcntl函数的F_SETFL命令,O_ASYNC为参数来实现
- 先调用信号是这号的SIGIO信号处理函数,然后使用fcntl函数设置套接字的属主
A. UDP套接字的SIGIO信号:信号产生的时刻点,一是套接字收到了一个数据报的数据包,二是套接字发生了异步错误,使用UDP套接字异步I/O的时候,我们使用recvfrom()函数来读取数据报数据或是异步I/O错误信息
B. TCP套接字的SIGIO信号:信号产生的时刻点很多,包括在一个监听了某个端口的套接字上成功建立了一个新的连接,一个断线的请求被成功初始化,一个断线的请求成功结束,套接字的某个通道被关闭,套接字接收到新数据,套接字将数据发送出去,发生了一个异步I/O错误
一个对信号驱动I/O 比较实用的方面是NTP(网络时间协议Network Time Protocol)服务器,它使用UDP。这个服务器的主循环用来接收从客户端发送过来的数据报数据包,然后再发送请求。对于这个服务器来说,记录下收到每一个数据包的具体时间是很重要的。因为那将是返回给客户端的值,客户端要使用这个数据来计算数据报在网络上来回所花费的时间。
5)异步I/O模式
异步I/O模式下,如果想进行I/O操作,只需要告诉内核我们要进行I/O操作,然后内核会马上返回。具体的I/O和数据拷贝全部由内核完成,我们的程序可以继续向下执行,当内核完成I/O操作和数据拷贝后,内核将通知我们的程序。其与信号驱动I/O区别是:信号驱动I/O模式下,内核在操作可以被操作的时候通知给我们的应用程序发送SIGIO信号,也就是在数据就绪的时候通知进程,完成数据拷贝后的步骤。而异步I/O模式下,内核在所有的操作都已经被内核操作结束后才通知应用程序,也就是在数据就绪以及数据拷贝完成后通知进程。
3. 几种I/O模式的比较
I/O模式 | 等待数据就绪 | 数据从内核拷贝到程序缓冲区 |
阻塞 | 初始化 ----------------------->结束 | |
非阻塞 | 检查/检查/检查/检查----------------------->结束 | |
多路复用 | 检查----阻塞--->就绪 初始化----->结束 | |
信号驱动 | 信号通知 初始化----->结束 | |
异步 | 初始化 信号通知 |
4.带外数据
带外数据是一种可以快速的通知网络的另一端计算机信息的一种方法.带外数据甚至可以只告诉远程计算机它的存在而不必将它的具体数据传输过去.带外数据并不是建立两个连接来传送数据(至少在TCP 中不是这样),它是将所谓的"带外数据"影射到已经存在的套接字连接中
Linux网络编程学习(十一) ----- 五种I/O模式(第六章)的更多相关文章
- Linux网络编程学习计划
由于网络编程是很重要的一块,自己这一块也比较欠缺,只知道一些皮毛,从今天开始系统学习<Linux网络编程>一书,全书分为十四个章节: 第一章 概论 P1-16 第二章 UNIX ...
- Linux网络编程学习(十二) ----- 结语
该书提前看完了,重点看了第四章和第六章,第七章以后只是大致浏览了一下,如果以后工作中涉及这一块再仔细研究一下,大概花了二十天的样子,主要了解了进程间的通信方式.socket编程以及五种I/O模式,看的 ...
- Linux网络编程学习路线
转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程 1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...
- Linux网络编程学习(十) ----- Socket(第六章)
前言:由于第五章主要介绍了TCP和UDP协议以及两者的包头的字段以及相应的功能,这里就不介绍了,对着字段看功能就好了,后续开始学习第六章 1.Socket Socket实质上就是提供了通信的端点,每个 ...
- Unix网络编程中的五种I/O模型_转
转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描 ...
- Linux网络编程学习(五) ----- 信号(第四章)
1.基本概念 进程阻塞: 进程执行条件得不到满足,就自动放弃CPU资源而进入休眠状态,以等待条件满足,当条件满足时,系统就将控制权还给该进程进行未完成的操作 共享资源: 进程间协调使用的系统资源 锁定 ...
- Linux网络编程学习(九) ----- 消息队列(第四章)
1.System V IPC System V中引入的几种新的进程间通信方式,消息队列,信号量和共享内存,统称为System V IPC,其具体实例在内核中是以对象的形式出现的,称为IPC 对象,每个 ...
- linux网络编程学习笔记之四 -----多-threaded服务器
对于使用过程中并发.通过实现更轻量级线程. 每个线程都是一个独立的逻辑流. 主题是CPU在执行调度的最小独立单位,这个过程是资源分配单元.当然,这是在微内核操作系统说.总之,这是唯一的一个操作系统内核 ...
- Linux网络编程学习(七) ----- 有名管道(第四章)
1.什么是有名管道?为什么有了管道还需要有名管道? 有名管道是解决管道不能提供非父子进程间通信的缺陷.管道在Linux系统内部是以文件节点(inode)的形式存在,但由于其对外的不可见性(“无名”性) ...
随机推荐
- proxmox网络
root@t1:~# cat /etc/network/interfaces# network interface settings; autogenerated# Please do NOT mod ...
- linux一些工具的安装(三)
linux(vmware15 centos7)中Docker安装 一.Docker卸载 1.查看已安装的docker安装包 $yum list installed|grep docker 执行后的 ...
- 如何下载github子目录文件
比如下载pai子目录下dockerfile文件,可以在浏览器键入 https://raw.githubusercontent.com/Microsoft/pai/master/src/dev-box/ ...
- windows 端口转发
1.添加端口转发 netsh interface portproxy add v4tov4 listenport=5000 listenaddress=10.30.3.148 connectport= ...
- Python脚本之Lrc歌词去时间轴转Txt文件,附带酷狗音乐APP关联已有krc歌词
一.Lrc歌词去时间轴转Txt文件 环境:Python2.7.x, Mac(Windows需装cygwin环境,当然你也可以自己改代码,Python新手,勿喷) # -*- coding: UTF-8 ...
- nginx1.14.0日志打印
nginx日志打印 http属性log_format来设置日志格式 ,参考 https://www.jb51.net/article/52573.htm <nginx日志配置指令详解> ...
- rediscluster安装
Redis 3.2.1集群搭建 一.概述 Redis3.0版本之后支持Cluster. 1.1.redis cluster的现状 目前redis支持的cluster特性: 1):节点自动发现 2) ...
- 7.2.4 else与if配对
规则是,如果没有花括号,else与离它最近的if匹配,除非最近的if被花括号括起来. 注意:要缩进"语句","语句"可以是一条简单语句或复合语句. 记住,编译器 ...
- mvc中让路由忽略带后缀的路径文件
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/ ...
- Intent之跳转总结
) { localIntent.setAction(; ActivityManager am = (ActivityManager) context.) {) { ) { // android 5.0 ...