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 ...
随机推荐
- window常见事件
<script type="text/javascript"> /*onunload = function(){ alert("onunload run&qu ...
- 如何获得中国所有的IP地址段
转自: https://wjianz.wordpress.com/2014/09/12/howto-%E4%BB%8Eapnic%E8%8E%B7%E5%8F%96%E4%B8%AD%E5%9B%BD ...
- Yii源码阅读笔记(二十三)
Module类中的辅助功能方法: /** * Returns an ID that uniquely identifies this module among all modules within t ...
- .gitignore文件不起作用
当我们用git时常常会习惯把我们不想上传到远程代码库中的一些本地文件(夹)放在一个叫做.gitignore的文件中,例如常见的本地build文件夹,一些IDE如Intellig,Eclipse的项目管 ...
- 【Composer】实战操作一:使用库
前言 前面我们简单介绍了composer的安装 以及 如何安装库 本文目的 主要实战讲解如何使用库,主要是PSR-0 和 PSR-4的区别,以及如何在代码中引用.关于PSR-0和PSR-4的具体区别可 ...
- linux 服务器对拷命令scp
1.今天在进行linux下服务部署时由于重新部署的繁杂,所以我决定用scp命令在linux线上服务器(A)拷贝一份服务程序到现有的服务器(B)上: 具体的操作命令是:scp -r A_username ...
- Redis配置文件(redis.conf)说明
Redis 配置 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONFIG 命令查看或设置配置项. 语法3> Redis CONFIG 命令 ...
- vi基本命令
http://www.cnblogs.com/younggun/p/3190820.html 要记得经常练习
- lodash的源码(1)
数组篇 1.compact,就是将数组中的false值去掉 function compact(array) { var index = -1, length = array ? array.lengt ...
- Elasticsearch 配置
Elasticsearch 配置 Elasticsearch不仅仅是Lucene和全文搜索,我们还能这样去描述它: 分布式的实时文件存储,每个字段都被索引并可被搜索 分布式的实时分析搜索引擎 可以扩展 ...