导语
随着JavaI/O库的不断迭代升级,基于Java 语言的网络编程也开始变的简单,随着异步I/O功能的增强,基于JavaNIO开发的网络服务器也越来越多。很多的互联网大厂都在不断的优化JavaNIO的开发。
对于网络编程来讲,最为基本的模型就是Server/Client模型,简单的说就是两个线程之间的通信。其中,Server服务端提供的是IP地址以及端口号,客户端通过TCP三次握手连接到服务端指定的IP地址与端口号。然后双方就可以通过Socket进行通信。
在之前的Java网络开发模型中,ServerSocket主要是负责提供服务端的IP端口等信息。而Socket则是作为客户端向服务端建立连接然后进行输入输出流的同步阻塞方式通信。
下面就来通过一个小例子来看看关于同步阻塞通信BIO相关的内容。如图所示
BIO通信模型,在服务端通常会有一个独立的Acceptor线程负责监听客户端的连接,收到客户端发送的连接之后,为每个客户端建立一个新的线程进行处理链路请求,处理完成之后,通过输出流的方式返回给客户端,然后线程进行销毁。这就是比较经典的一请求一应答的通信模型。
这个模型最大的问题就是不能够弹性伸缩,当客户端的访问量增加之后,服务端的线程数将会与客户端的数量呈1:1的正比关系,由于线程是JVM中比较宝贵的系统资源,在线程数暴涨之后,系统的性能也将下降,随着并发量的逐渐增大,系统会发生线程堆栈溢出、创建新的线程失败等问题,最终就会导致JVM不能提供服务。
下面就通过一个小例子来进行测试
public class TimeServer {
public static void main(String[] args) {
int port = 8080;
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(port);
System.out.println("The time server is start in port : "+ port);
Socket socket = null;
while (true){
socket = serverSocket.accept();
new Thread(new TimeServerHandler(socket)).start();;
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (serverSocket!=null){
System.out