在本章巾,我们会分别对 JDK 的BIO ,NIO 和JDK 1.7 最新提供的 NI02.0的使用进行详细说明 ,通过流程图和代 码讲解,让大 家体会到随着 Ja va 1/0 类库的 不断发展和改进,基于 Java 的网络编程会变得越来越简单 ,随着异步 I/0 功 能的增强,基于Java NIO 开发 的网络服务器甚至不逊色于采用 C++开发的网络程序 。
本章主要 内容包括 :
1.传统的 同步阻塞式 1/0 编程
2.基于 NIO 的非阻塞编程
3.基于 NI02 .0 的异步非阻塞 ( AJO )编程
4.为什么要使用 NIO 编程
5.为什 么选择N etty
2.1 传统的 BIO 编程
网络编程 的基本模型是 Client/Server 模型 ,也就是两个进程 之 间进行相互通信 ,其 中 服务端提供位 置信息 ( 绑定的 IP 地址和监听端口 ) ,客户端通过连接操作 向服务端监听的址发起连接请求 ,通过三次握手建立连接 ,如果连 接建立成功,双方就可以通过 网络套接字 ( Socket ) 进行通信 。
在基于传统同步阻塞模型开发中 ,
Server Socket 负责绑定 IP 地址 ,启动监昕端 口:
Socket 负责发起连接操作 。连接 成功之后 ,双方通过输入 和输 出流进行同步阻塞式通信 。
下雨,我们就 以经典的时间服务器 ( TimeServer ) 为例 ,通过代码 分析来回顾和 熟悉 下 BIO 编程 。
2.1 .1 BIO 通信模型图
首先 ,我 们通过图 2- 1 所示 的通信模型图 来熟悉BIO 的服务端通信模型 :采用 BIO 通信模型的服务端 ,通 常 由一个独立 的 Acceptor 线程负责监听客户端的连 接 ,它接 收到客 户端连接请求之后为每个客户端创建 一个新 的线程进行处理 ,处理完成之后 ,通过 输 出流返 回应答给客户端 ,线程销毁 。这就是 典型的一请求 一应答通信模型。
该模型最大的问题就是缺乏弹性伸缩 能力 ,当客户 端并发访问量增加后 ,服 务端的线 程个 数和客户端并发访 问数量. 1 : 1 的正 比关系 ,由于线程 是 Java 虚拟机非常宝贵的系统 资源 ,当线程数膨胀之后 ,系统的 性 能将急剧 下降,随着并发访问量 的继续增大 ,系统会 发生线程堆溢出、创建新线程 失败等问题 ,并最 终导致进程岩机或者僵死,不能对外提 供服 务 。
下面的两个小节 ,我们会 分别对服务端和客户端进行源码分析,寻找同 步阻塞I/0的弊端 。
2. 1.2 同步阻塞式 1/0 创建 的 Timeserver 源码分析
代码 清单 2-1同步 阻塞 I/0 的 TimeServer
( 备注 :以 下代 码行号 均 对应 源 代码 中实 际行号 。)