JAVA基础知识之网络编程——-网络通信模型(IO模型)
《Unix网络编程:卷1》中介绍了5中I/O模型,JAVA作为运行在宿主机上的程序,底层也遵循这5中I/O模型规则。这5中I/O模型分别是:
- 阻塞式IO
- 非阻塞式IO
- I/O复用
- 信号驱动式IO
- 异步IO
按POSIX标准来分,IO分为同步和异步,上面的前4钟都属于同步IO,具体后面解释。
在介绍IO模型之前,需要先了解应用程序IO的过程,一般来说,一个IO分为两个阶段
应用程序向操作系统发出IO请求:应用程序发出IO请求给操作系统内核,操作系统内核需要等待数据就绪,这里的数据可能来自别的应用程序或者网络
- 等待数据:数据可能来自其他应用程序或者网络,如果没有数据,操作系统就一直等待,应用程序就跟着等待。
- 拷贝数据:将就绪的数据拷贝到应用程序工作区。
在Unix系统中,操作系统的IO操作是一个系统调用recvfrom(),即一个系统调用recvfrom包含两步,等待数据就绪和拷贝数据。
阻塞式IO模型
正如上面的IO操作的步骤,当应用程序发起IO请求之后,操作系统就要处理系统调用recvfrom(),在这个过程中,操作系统需要等待数据就绪(数据可能来自别的应用程序的输入或者网络),应用程序则不再处理别的事情,而是一直等待(即阻塞状态)数据就绪,然后操作系统完成IO操作,然后recvfrom()才方法返回,应用程序才继续执行,这就是阻塞式IO模型。下图描述了阻塞式IO模型

非阻塞式IO模型
当应用程序发起了IO请求之后,系统调用recvfrom()被执行,并且立即返回,但是返回的并不是IO处理完成的结果,而是一个特定的错误,表示IO数据没有准备好,因此不需要进行IO操作。应用程序会不停地(即轮询)执行recvfrom()系统调用,直到数据已经就绪,然后操作系统完成IO操作,recvfrom()返回成功。这个过程中,没有数据就绪时系统调用recvfrom()是立即返回的,即应用程序并没有阻塞在底层操作系统的等待数据上面,而是轮询结果。这个过程可以用下图表示,
可见阻塞IO与非阻塞IO的关键区别在于,系统调用recvfrom是否立即返回。由于轮询会消耗大量CPU时间,因此这种模式并不常用。

IO复用模型(多路复用)
前面的非阻塞IO将会轮询一个IO是否可用,而IO复用则是轮询多个IO是否至少有一个可用。
IO复用的关键在于select()函数。在阻塞IO中,应用程序阻塞在一个IO的内核操作上;
但在多路复用中,通过select(),可以同时监听多个IO请求的内核操作,只要有任意一个IO的内核操作就绪,都可以通知select()返回,再进行系统调用recvfrom()完成IO操作。
这个过程应用程序就可以同时监听多个IO请求,这比起基于多线程阻塞式IO要先进得多,因为服务器只需要一两个线程就可以进行多客户端通信。IO复用可用下图表示,

信号驱动式IO模型
在unix系统中,应用程序发起IO请求时,可以给IO请求注册一个信号函数,请求立即返回,操作系统底层则处于等待状态(等待数据就绪),直到数据就绪,然后通过信号通知主调程序,主调程序才去调用系统函数recvfrom()完成IO操作。
信号驱动也是一种非阻塞式的IO模型,比起上面的非阻塞式IO模型,信号驱动式IO模型不需要轮询检查底层IO数据是否就绪,而是被动接收信号,然后再调用recvfrom执行IO操作。
比起多路复用IO模型来说,信号驱动IO模型针对的是一个IO的完成过程, 而多路复用IO模型针对的是多个IO同时进行时候的场景。 信号驱动式IO模型用下图表示,

异步IO模型
异步IO模型的工作机制是,将整个IO操作(包括等待数据就绪,复制数据到应用程序工作空间)全都交给操作系统完成,操作系统完成整个过程之后,再通知应用程序。
异步IO模型跟信号驱动IO模型很相似,但是区别是信号驱动模型是在数据就绪的时候通知应用程序,应用程序再调用系统函数recvfrom进行IO操作。
而异步IO模型则是数据就绪且操作系统已经将数据拷贝进应用程序运行空间之后,操作系统再通知应用程序,这个过程中应用程序不需要阻塞。异步IO可以如下图表示,

IO模型对比
可见前面四种IO模型中,应用程序都会在某一环节阻塞(即使是轮询,也算是一种阻塞),POSIX将这种IO模型称为同步IO操作,
而异步IO模型,则是全权把IO操作整个过程都交给操作系统,中途无阻塞,POSIX将这种IO模型称为异步IO操作。 以上所有IO对比如下图,

JAVA基础知识之网络编程——-网络通信模型(IO模型)的更多相关文章
- JAVA基础知识之面向对象编程知识汇总
JAVA基础课程部分面向对象已经学习完成,知识结构如下: 总体知识框架: 类的结构: 面向对象编程三大特征: 关键字和抽象类接口等: 常见知识汇总: 成员变量和局部变量比较 有无返回值方法比较: 权限 ...
- JAVA基础知识总结17(网络编程)
端口: 物理端口:IP地址 逻辑端口:用于标识进程的逻辑地址,不同进程的标识:有效端口:0~65535,其中0~1024系统使用或保留端口. JAVA中ip对象:InetAddress. import ...
- JAVA基础知识之JDBC——编程步骤及执行SQL
JDBC编程步骤 下面以mysql数据库为例, 1.加载驱动 首先需要下载数据库的驱动jar文件,并且在eclipse包中加入到class path中去, 例如mysql的驱动文件 mysql-con ...
- JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)
本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...
- Java基础复习笔记系列 九 网络编程
Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...
- [转] - Linux网络编程 -- 网络知识介绍
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- java基础知识精华
转载:https://www.jianshu.com/p/6c078abb720f java基础知识 java内存模型 java运行时数据区域 hashMap 如何解决冲突 存储方式 冲突达到一定数量 ...
- 学习Spring必学的Java基础知识(1)----反射(转)
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...
- 学习Spring必学的Java基础知识(1)----反射
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...
- Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
随机推荐
- 34款Firefox渗透测试插件工具
工欲善必先利其器,firefox一直是各位渗透师必备的利器,小编这里推荐34款firefox渗透测试辅助插件,其中包含渗透测试.信息收集.代理.加密解密等功能. 1:Firebug Firefox的 ...
- mysql sql注入
防止SQL注入,我们需要注意以下几个要点: 1.永远不要信任用户的输入.对用户的输入进行校验,可以通过正则表达式,或限制长度:对单引号和 双"-"进行转换等. 2.永远不要使用动态 ...
- HashMap实现原理分析
1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1 ...
- Codeforces Round #346 (Div. 2) E F
因为很久没有个人认真做题了 昨天晚上开了场虚拟cf来锻炼个人手速 选的是第一次做cf的场 那时候7出3还被hack...之后也没补题 这次做的时候顺便回忆了一下以前比赛的时候是怎么想的 发现经验还是很 ...
- linux chmod 命令
Avril 首页 新随笔 管理 随笔 - 153 文章 - 1 评论 - 58 修改linux文件权限命令:chmod Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何 ...
- flush vs ob_flush
刷新PHP程序的缓冲,而不论PHP执行在何种情况下(CGI ,web服务器等等).该函数将当前为止程序的所有输出发送到用户的浏览器. flush() 函数不会对服务器或客户端浏览器的缓存模式产生影响. ...
- Theos
一.安装 1.配置环境变量 (每次 terminal 重新启动需要配置) $ export THEOS=/opt/theos 2.下载 Theos $ sudo git clone git://git ...
- MySQL创建数据库并赋予权限
1.创建一个mysql用户并设置密码create user 'MySql用户名'@'localhost' identified by '密码';2.限制账户资源grant usage on *.* t ...
- Python基础二. 数据结构、控制流、运算符、真值测试
一.概述 数据结构上广义上有两种,单一类型和集合类型 单一类型,表示一种对象 集合类型,表示包含多种对象 Python 中的内建的数据类型有str.list.tuple.dict.set.number ...
- Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...