jdk1.6及之前都只实现BIO 和 NIOjdk1.7开始支持AIO,即NIO 2.0在BIO阻塞模式下server端:1 new ServerSocket(int port) 监听端口2 serverSocket.accept() 阻塞式等待客户端的连接,有连接才返回Socket对象3 socket.getINputStream() 获取客户端发过来的信息流4 socket.getOutputStream() 获取输出流对象,从而写入数据返回客户端client端:1 newSocket(String host,int port) 建立与服务器端的连接,如果服务器没启动,报Connection refused异常2 socket.getInputStream() 读取服务器端返回的流3 socket.getOutputStream() 获取输出流,写入数据发送到服务器端在NIO模式下Server端:1 ServerSocketChannel.open() 获取serverScoketChannel实例2 serverScoketChannel.configueBlocking(false) 设置channel为非阻塞模式3 serverSocketChannel.socket() 获取serverSocket对象4 serverSocket.bind(port) 监听端口5 Selector.open() 打开Selector,获取selector实例6 serverSocketChannel.register(Selector,int) 向selector注册channel和感兴趣的事件7 while(true) 循环以保证正常情况下服务器端一直处于运行状态8 selector.select() 获取selector实例中需要处理的SelectionKey的数量9 for(SelectionKey key:selector.selectedKeys()) 遍历selector.selectedKeys,以对每个SelectionKey的事件进行处理10 key.isAcceptable() 判断SelectionKey的类型是否为客户端建立连接的类型11 key.channel() 当SelectionKey的类型是acceptabel时,获取绑定的ServerSocketChannel对象12 serverSocketChannel.accept() 接受客户端建立连接的请求,并返回SocketChannel对象13 socketChannel.regiseter(Selector,int) 向Selector注册感兴趣的事件类型,如read,write14 key.isReadable() 判断SelectionKey是否为readable,如是则意味着有消息流在等待处理15 socketChannel.read(ByteBuffer) 从SelectionKey中绑定的SocketChannel对象读取消息流16 socketChannel.write(ByteBuffer) 从SelectionKey中绑定的SocketChannel对象输出消息流
client端:
1 SocketChannel.open() 打开SocketChannel
2 SocketChannel.configureBlocking(false) 将SocketChannel配置为非阻塞模式
3 SocketChannel.connect(host,port) 连接到指定的目标地址
4 Selector.open() 打开Selector
5 SocketChannel.register(Selector,int) 向Selector注册感兴趣的事件,connected,read,write
6 while(true) 循环执行保证客户端一直处于运行状态
7 Selector.select() 从Selector中获取是否有可读的key信息
8 for(SelectionKey key:selector.selectedKeys()) 遍历selector中所有selectedKeys
9 SelectionKey.isConnectable() 判断是否为连接建立的类型
10 SelectionKey.channel() 获取绑定的SocketChannel
11 SocketChannel.finishConnect() 完成连接的建立(TCP/IP的三次握手)
12 SelectionKey.isReadable() 判断是否为可读类型
13 SelectionKey.channel() 获取绑定的SocketChannel
14 SocketChannel.read(ByteBuffer) 从SocketChannel中读取数到ByteBuffer中
15 SocketChannel.write(ByteBuffer) 向SocketChannel中写入ByteBuffer对象数据
同步非阻塞IO(NIO)
NIO是基于事件驱动思想的,实现上通常采用Reactor(http://en.wikipedia.org/wiki/Reactor_pattern) 模式,从程序角度而言,当发起IO的读或写操作时,是非阻塞的;当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理, 应用再将流读取到缓冲区或写入操作系统。对于网络IO而言,主要有连接建立、流读取及流写入三种事件、linux2.6以后的版本使用epoll(http://lse.sourceforge.net/epoll/index.html)方式实现NIO。
select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。它的流程如图:
当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个 socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
这个图和blocking IO的图其实并没有太大的不同,事实上,还更差一些。因为这里需要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。但是,用select的优势在于它可以同时处理多个connection。(多说一句。所以,如果处理的连接数不是很高的话,使用 select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。)
在IOmultiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,整个用户的process其实是一直被 block的。只不过process是被select这个函数block,而不是被socket IO给block。
AIO,异步IO方式
AIO为异步IO方式,同样基于事件驱动思想,实现上通常采用Proactor模式(http://en.wikipedia.org/wiki/Proactor_pattern)
从程序的角度而言,与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均 为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方 法传递的流写入完毕时,操作系统主动通知应用程序。较之NIO而言,AIO一方面简化了程序出的编写,流的读取和写入都由操作系统来代替完成;另一方面省 去了NIO中程序要遍历事件通知队列(selector)的代价。Windows基于IOCP(http://en.wikipedia.org/wiki/Input/output_completion_port)实现了AIO,Linux目前只有基于epoll实现的AIO。
jdk1.6及之前都只实现BIO 和 NIOjdk1.7开始支持AIO,即NIO 2.0在BIO阻塞模式下server端:1 new ServerSocket(int port) 监听端口2 serverSocket.accept() 阻塞式等待客户端的连接,有连接才返回Socket对象3 socket.getINputStream() 获取客户端发过来的信息流4 socket.getOutputStream() 获取输出流对象,从而写入数据返回客户端client端:1 newSocket(String host,int port) 建立与服务器端的连接,如果服务器没启动,报Connection refused异常2 socket.getInputStream() 读取服务器端返回的流3 socket.getOutputStream() 获取输出流,写入数据发送到服务器端在NIO模式下Server端:1 ServerSocketChannel.open() 获取serverScoketChannel实例2 serverScoketChannel.configueBlocking(false) 设置channel为非阻塞模式3 serverSocketChannel.socket() 获取serverSocket对象4 serverSocket.bind(port) 监听端口5 Selector.open() 打开Selector,获取selector实例6 serverSocketChannel.register(Selector,int) 向selector注册channel和感兴趣的事件7 while(true) 循环以保证正常情况下服务器端一直处于运行状态8 selector.select() 获取selector实例中需要处理的SelectionKey的数量9 for(SelectionKey key:selector.selectedKeys()) 遍历selector.selectedKeys,以对每个SelectionKey的事件进行处理10 key.isAcceptable() 判断SelectionKey的类型是否为客户端建立连接的类型11 key.channel() 当SelectionKey的类型是acceptabel时,获取绑定的ServerSocketChannel对象12 serverSocketChannel.accept() 接受客户端建立连接的请求,并返回SocketChannel对象13 socketChannel.regiseter(Selector,int) 向Selector注册感兴趣的事件类型,如read,write14 key.isReadable() 判断SelectionKey是否为readable,如是则意味着有消息流在等待处理15 socketChannel.read(ByteBuffer) 从SelectionKey中绑定的SocketChannel对象读取消息流16 socketChannel.write(ByteBuffer) 从SelectionKey中绑定的SocketChannel对象输出消息流
client端:
1 SocketChannel.open() 打开SocketChannel
2 SocketChannel.configureBlocking(false) 将SocketChannel配置为非阻塞模式
3 SocketChannel.connect(host,port) 连接到指定的目标地址
4 Selector.open() 打开Selector
5 SocketChannel.register(Selector,int) 向Selector注册感兴趣的事件,connected,read,write
6 while(true) 循环执行保证客户端一直处于运行状态
7 Selector.select() 从Selector中获取是否有可读的key信息
8 for(SelectionKey key:selector.selectedKeys()) 遍历selector中所有selectedKeys
9 SelectionKey.isConnectable() 判断是否为连接建立的类型
10 SelectionKey.channel() 获取绑定的SocketChannel
11 SocketChannel.finishConnect() 完成连接的建立(TCP/IP的三次握手)
12 SelectionKey.isReadable() 判断是否为可读类型
13 SelectionKey.channel() 获取绑定的SocketChannel
14 SocketChannel.read(ByteBuffer) 从SocketChannel中读取数到ByteBuffer中
15 SocketChannel.write(ByteBuffer) 向SocketChannel中写入ByteBuffer对象数据
分享到:
相关推荐
对java io总结时编写的测试代码,包括BIO,NIO,AIO的实现,Java io操作是编程人员经常使用到的,以前只是使用没有对这三种IO做系统的了解,本文将对这三种IO作详细的介绍并附有测试完整代码
bio nio aio demo下载,可直接运行main方法。了解 bio nio aio基础用法
基于java的BIO、NIO、AIO通讯模型代码实现
其实NIO这类代码都有一些比较统一的写法,因此将BIO,NIO,AIO的实现代码貼出来进行分享,有需要可以下载,直接执行对应的SERVER和CLIENT端的main函数即可
BIO,NIO,AIO,Netty面试题
一站式学习Java网络编程 全面理解BIO:NIO:AIO1
netty案例,netty4.1基础入门篇零《初入JavaIO之门BIO、NIO、AIO实战练习》 ...
BIO、NIO、AIO
BIO,NIO,AIO,Netty面试题
java 网络通信 aio bio nio 例子 参考以下网址 https://blog.csdn.net/anxpp/article/details/51512200
java的bio nio aio 几种io的详细解释
用Java代码来告诉您什么是BIO, 什么是NIO, 什么是AIO
主要是介绍java方面网络方面 网络通信方面的面试题,核心内容主要是关于BIO,NIO,AIO,Netty的面试,算是一套八股文吧,还是老话,该背的还是要背一背!!!
IO模型决定了数据的传输方式,Java支持BIO,NIO,AIO三种IO模型。BIO是同步阻塞模型,特点是一对一的客户端与处理线程关系,适用场景是连接数量较小并且固定的,优点是编程简单,但对服务器资源要求高。NIO是同步非...
BIO,NIO,AIO,Netty面试题 35道,面试通关宝典
【Java IO】从NIO到Reactor三种模式 博客地址:https://blog.csdn.net/qq_36963950/article/details/107998164
BIO、NIO、AIO、Netty 、TCP全网最全解析!Netty中提供了哪些线程模型?
BIO、NIO、AIO、Netty 什么是IO:Java中I/O是以流为基础进行数据的输入输出的,所有数据被串行化(所谓串行化就是数据要按顺序 进行输入输出)写入输出流。简单来说就是java通过io流方式和外部设备进行交互。在Java...