基于Java的socket I/O流技术
2017-06-03王少辉陈晓鹏
王少辉++陈晓鹏
摘 要传统的BIO技术在网络通信中需要服务器为每一个链接都建立一个线程,如果其中已连接的请求没有任何操作,将造成线程浪费。本文分析了BIO技术、NIO技术、AIO技术在网络通信中的应用场合,解决了传统BIO技术的不足,给出了其基本实现步骤及应用场景。
【关键词】I/O NIO BIO SOCKET通信 Java 多线程
1 引言
传统BIO技术在Socket通信中,系统需要为每一个链接建立一个线程去处理其请求,随着客户端的并发量不断增加后,会导致线程数量的增加严重影响系统的性能。由于并发量的增加有可能导致服务器宕机,严重影响到用户在使用过程中的良好体验。为解决传统BIO的不足,Java 中提供了新的API----NIO和NIO2来解决由于BIO技术带来的系统瓶颈问题。在NIO中系统不再为每一个用户请求注册一个线程,而是通过通道将每一个链接都注册到多路复用器上,通过多路复用器对注册在其上的链接进行轮询检查,发现有链接请求才会开启线程对其进行处理。NIO只在有连接请求时selector才会不断轮询检查通道IO操作是否完成,与NIO技术不同的是AIO技术是异非步阻塞的。AIO中不再需要多路复用器,而是由异步非阻塞通道直接操作read和write方法。在客户端读写请求发出后不再等待服务器的响应,而是处理完成后由操作系统来通知应用程序。AIO与NIO这两种技术都极大地改变了传统I/O流的不足。
2 Socket基本通信原理介绍
Socket是网络通信中的其中一方,用来接收网络通信中双方其中一方的请求,方便的对双方的数据进行传输。Socket通信分有连接的和无连接,面向连接的Socket通信与面向非连接的Socket通信相比有更高的可靠性和更有效的数据传输。本文基于有连接的套接字传输。
3 BIO、NIO、AIO技术比较
3.1 BIO技术简介
BIO技术同步并且阻塞,在这种情况下,服务器需要为每一个连接开启一个线程,只要有客户端有请求服务器就需要开启线程去进行处理。从客户端传来的每个请求,服务器都需要为其创建相应的线程去处理其请求。在BIO中,由于其线程的开销很大,适合于运用在并发量小的场景下。其基本模型如图1所示。
BIO网络通信基本步骤:
3.1.1 服务低端
(1)创建ServerSocket并绑定监听端口;
(2)创建Socket用来接收客户端请求;
(3)创建输入输出流用来接收客户端输入或向客户端输出数据;
(4)关闭输入输出流等系统资源。
3.1.2 客户端
(1)创建Socket绑定IP地址及端口;
(2)创建输入输出流用来接收服务器端相应或向服务器端发送数据;
(3)关闭输入输出流等系统资源。
3.2 NIO技术简介
NIO技术即New IO技术,NIO技术由很多类和组件构成,其最重要的由channel、Buffer、和Selectors三个核心部分组成。
Channel:Java NIO中的通道类似于流,但又不完全相同。既可以从通道中读取数据到Buffer也可以将数据从Buffer写入通道中。其中SocketChannel和ServerSocketChannel是NIO中提供的用来解决Socket通信中的服务器性能问题的。SocketChannel通过TCP协议来读取网络中的数据,ServerSocketChannel用来接收链接来的请求以供服务器相应。
Buffer:Buffer是用来为数据提供缓冲区的。在NIO技术中,所有的数据都必须经过缓冲区。缓冲区本质上为一块可读可写的内存块,NIO中提供了不同数据类型的缓冲区来处理不同的数据请求,和一些基本的方法来操作缓冲区中的数据。
Selector:Selector是单线程来处理多个链接请求的关键。在Socket通信中,如果将多个链接请求注册到多路复用器上,就可以用一个线程来处理多个链接请求,这样就提高了Socket通信的效率。NIO通信中的网络模型
如图2所示。
NIO通信基本步骤:
3.2.1 服务器端
(1)创建多路复用器Selector 用来选择通道;
(2)创建服务器端通道ServerSocketChannel;
(3)为多路复用器上注册ServerSocketChannel用来将数据通过通道读写;
(4)申请Buffer存储数据;
(5)多路选择器通过其key值轮询检查通道读写Buffer中的数据完成其通信过程。
3.2.2 客戶端
(1)创建IP地址和端口号对应的SocketChannel ;
(2)将SocketChannel设置为非阻塞模式;
(3)创建多路复用器Selector注册SocketChannel到多路选择器;
(4)多路选择器轮询检查通道从Buffer中读写数据。
在NIO网络通信模型中,客户端向服务器端发起链接请求,客户端将数据写入服务器端Buffer中,然后通过channel来从Buffer读取数据或向Buffer写入数据,对于通道中的数据必须经过选择器来向服务器端的线程发起请求。而每一个多路选择器对应一个线程模型,这样一来,只有当链接请求有效时服务器才为客户端开启线程处理数据。对于同步阻塞的NIO模型中客户端在向服务器端发送完数据后会不断询问I/O操作是否就绪才能进行下一步的操作。此模型中由于不需要为每一个链接请求创建一个线程,大大减少了线程之间的切换带来的巨大开销。提高了I/O的效率,使得在socket网络通信更加高效。但由于NIO在链接请求中会不断询问I/O操作是否完成,其适合运用在短链接且并发量大的场合下。
3.3 AIO技术简介
AIO即为异步非阻塞IO,与NIO不同的是,在这种模式下,客户端发起一个链接请求后不在询问服务器端的I/O操作是否完成便立即返回。在使用过程中只需直接调用异步的read和write方法来读写数据,在读写过程完毕后由操作系统主动通知应用程序读写操作是否完成。由AIO的读写过程可以看出,因为在读写完成后客户端不需要再询问服务器端是完成了I/O操作,所以AIO非常适合于运用在那些并发量大且长连接的请求。AIO模型如图3所示。
AIO中有几个比较重要的类:
AsynchronousServerSocket:用来创建服务器端的ServerSocket并绑定地址监听端口。
AsynchronousSocketChannel:Socket在异步非阻塞通信中的应用,用来表示一个连接请求,并用来在通信过程中传递数据。
AsynchronousChannelGroup:异步通道的分组管理,目的是问了资源共享。创建AsynchronousChannelGroup时需要为其绑定一个线程执行器对象,这个线程池主要完成两个任务:处理I/O事件和派发CompletionHandler。在创建AsynchronousServerSocket时需要为其绑定一个AsynchronousChannelGroup。通过AsynchronousServerSocket创建的AsynchronousChannelGroup将属于同一组,共享其中资源。
CompletionHandler:用于定义在异步IO操作完成后的回调接口。
3.3.1 服务器端
(1)创建AsynchronousChannelGroup;
(2)创建AsynchronousServerSocketChannel并将它绑定在AsynchronousChannelGroup上;
(3)为AsynchronousServerSocketChannel对象绑定端口号;
(4)调用accept()接收客户端请求实现CompletionHandler接口调用读写方法进行读写数据。
3.3.2 客户端
(1)创建AsynchronousSocketChannel;
(2)绑定IP地址和端口号链接服务低端实现CompletionHandler接口中方法直接进行读写数据。
3.4 各种I/O技術比较分析
BIO:同步阻塞I/O,使用难度简单,可靠性低,适用于链接并发量小的架构且对服务器资源依赖更高。
NIO:同步非阻塞I/O,使用难度复杂,可靠性高,适用于并发量大且链接较短的场景。
AIO:异步非阻塞I/O,使用难度一般,可靠性高,适用于并发量大且链接长的场景。
4 结语
传统网络在IO处理方面存在着性能不足的问题,NIO与AIO包的引入解决了传统IO性能瓶颈问题,使的Java在网络通信中有了更搞得效率。对于不同的IO来说,它们各自有有不同的应用领域。对于那些并发量小,数据传输量小的场景来说,传统的BIO完全可以胜任其工作。相反对于那些对性能要求比较高,并发量大且对IO的要求比较搞得场合来说应该选择NIO或者BIO技术。如果客户端与服务器在长连接的情况下选择AIO相比NIO会更加高效一些。相反,如果是短连接的应用领域,则推荐使用NIO。
参考文献
[1]范宝德,马建生.Java非阻塞通讯研究[J].微计算机信息,2006,22(12-3):116-119.
[2]刘邦桂,李正凡.用Java实现流式Socket通讯[J].华东交通大学学报,2007,24(05):110-112.
[3]封玮,周世平.基于Java NIO的非阻塞通信的研究与实现[J].计算机系统应用,2004(09):32-35.
[5]任小强,陈金鹰,李文彬,胡波.网络通信之Java Socket多线程通信[J].信息通信,2015(06):206-207.
作者简介
王少辉(1992-),男,山西省平顺县人。硕士学位。现为山东大学(威海)机电与信息工程学院学生。主要研究方向为电路与系统。
陈晓鹏(1992-),男,天津市人。硕士学位。现为山东大学(威海)机电与信息工程学院学生。主要研究方向为电路与系统。
作者单位
山东大学(威海)机电与信息工程学院 山东省威海市 264209