Java基础-IO流-网络IO

Java工程师知识树 / Java基础


一、网络IO

网络编程的基本模型是C/S模型,即两个进程间的通信
服务端提供IP和监听端口客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手连接,如果连接成功建立,双方就可以通过套接字进行通信。 通信的方式就是指网络IO

JDK1.7之后有网络编程模型:

  1. BIO
  2. NIO
  3. AIO

BIO(传统的同步阻塞模型)开发中,ServerSocket负责绑定IP地址,启动监听端口;Socket负责发起连接操作。连接成功后,双方通过输入和输出流(网络IO)进行同步阻塞式通信。

NIO提供了与传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现。

AIO(NIO 2.0)引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。异步的套接字通道时真正的异步非阻塞I/O,对应于UNIX网络编程中的事件驱动I/O(AIO)。AIO不需要过多的Selector对注册的通道进行轮询即可实现异步读写,从而简化了NIO的编程模型。

一、BIO流

BIO是一个典型的网络编程模型,是通常我们实现一个服务端程序的过程,步骤如下:

    1. 主线程accept请求阻塞
    1. 请求到达,创建新的线程来处理这个套接字,完成对客户端的响应。
    1. 主线程继续accept下一个请求

这种模型有一个很大的问题是:当客户端连接增多时,服务端创建的线程也会暴涨,系统性能会急剧下降。因此,在此模型的基础上,类似于 tomcat的bio connector,采用的是线程池来避免对于每一个客户端都创建一个线程。有些地方把这种方式叫做伪异步IO(把请求抛到线程池中异步等待处理)。

Java基础-IO流-网络IO_第1张图片

二、NIO

JDK1.4开始引入了NIO类库,这里的NIO指的是New IO,主要是使用Selector多路复用器来实现。Selector在Linux等主流操作系统上是通过epoll实现的。

NIO的实现流程,类似于select:

    1. 创建ServerSocketChannel监听客户端连接并绑定监听端口,设置为非阻塞模式。
    1. 创建Reactor线程,创建多路复用器(Selector)并启动线程。
    1. 将ServerSocketChannel注册到Reactor线程的Selector上。监听accept事件。
    1. Selector在线程run方法中无线循环轮询准备就绪的Key。
    1. Selector监听到新的客户端接入,处理新的请求,完成tcp三次握手,建立物理连接。
    1. 将新的客户端连接注册到Selector上,监听读操作。读取客户端发送的网络消息。
    1. 客户端发送的数据就绪则读取客户端请求,进行处理。

相比BIO,NIO的编程非常复杂。

Java基础-IO流-网络IO_第2张图片

三、AIO

JDK1.7引入NIO2.0,提供了异步文件通道和异步套接字通道的实现。其底层在windows上是通过IOCP,在Linux上是通过epoll来实现的(LinuxAsynchronousChannelProvider.java,UnixAsynchronousServerSocketChannelImpl.java)。

    1. 创建AsynchronousServerSocketChannel,绑定监听端口
    1. 调用AsynchronousServerSocketChannel的accpet方法,传入自己实现的CompletionHandler。包括上一步,都是非阻塞的
    1. 连接传入,回调CompletionHandler的completed方法,在里面,调用AsynchronousSocketChannel的read方法,传入负责处理数据的CompletionHandler。
    1. 数据就绪,触发负责处理数据的CompletionHandler的completed方法。继续做下一步处理即可。
    1. 写入操作类似,也需要传入CompletionHandler。

其编程模型相比NIO有了不少的简化。

你可能感兴趣的:(Java基础-IO流-网络IO)