Java NIO

作者: 廿陆小生 | 来源:发表于2017-10-06 08:57 被阅读0次

    说到netty,不得不提的一个就是Java NIO。本文主要介绍JAVA NIO涉及到的一些基础概念以及对JAVA NIO的开发过程进行简单介绍。

    基本概念

    Java NIO,一般称为非阻塞IO,它基于多路复用模型。它有三个基本的概念:Channel(通道),Buffer(缓冲区),Selector(多路复用器)。

    channel 通道

    channel是一个全双工通道,不同于的流的地方,它可以同时用于读和写。因为它是全双工的,可以比流更好地映射底层操作系统的API,它代表了一个面向流的可监听读写事件的socket。 channel主要分为两大类,分别是用于网络读写的SelectableChannel和用于文件读写的FileChannel,其中SelectableChannel又提供了两个子类,分别是面向服务端的ServerSocketChannel和面向SocketChannel。

    Buffer 缓冲区

    在 Java NIO中,所有的数据都是通过缓冲区进行处理的。在读取的时候,将数据读取到缓冲区;在写入数据时,也是将数据写入到缓冲区的。最常用是缓冲区是ByteBuffer。

    Selector

    Selector是Java NIO中的多路复用器。 它的主要作用就是提供已经就绪的任务,Selector会不断轮询注册在其上的Channel,如果某个Channel上有新的连接接入、读和写事件,这个Channel就会被轮询出来,然后通过SelectionKey可以获取整个就绪的Channel集合,进行后续的IO操作。

    可以将多个Channel注册到一个Selector上,使用一个线程处理所有的IO事件,也可以将多个Channel注册到多个Selector实例上,利用多线程的高性能处理IO事件。

    编程步骤

    服务端

    Java NIO提供的API较为繁琐,此处就不上代码了,对于多路复用模型,服务端和前文中使用python编写的过程很类似,主要有以下几点:

    • 创建一个负责监听新连接的socket
    • 通过系统调用得到一个处于就绪状态的连接集合
    • 创建一个循环用来轮询这个集合
    • 判断事件类型。如果是Accept,则创建新的连接并为其注册事件,如果是读写数据,则作读写处理

    下面是Java NIO服务端端的序列图:

    1. 创建ServerSocketChannel,设置为非阻塞模式
    2. 设置ServerSocketChannel参数,绑定监听地址
    3. 创建一个线程,用来轮询多路复用器Selector
    4. 将ServerSocketChannel注册到Selector,监听SelectionKey.Accept事件
    5. 在循环中使用Selector.select()获取就绪状态的channel,对事件类型进行判断:
      • 如果是Accept事件,则调用ServerSocketChannel.accept()创建新的客户端连接,将其设置成非阻塞模式,并注册到Selector监听感兴趣的操作(read、write)
      • 如果是Read事件,则需构造ByteBuffer对象,读取数据包
      • 如果是Write事件,则继续发送数据包

    客户端

    1. 创建SocketChannel,设置成非阻塞,设置Tcp参数
    2. 连接服务端,如果连接成功,则向selector注册读写事件,进行IO操作
    3. 如果连接失败,则向selector注册CONNECT事件,轮询处理。

    总结

    Java NIO提供的接口使用起来较为复杂,netty封装了更为简单的方法,并且netty自身的线程模型也是实现更性能的关键,后面会做介绍。

    相关文章

      网友评论

          本文标题:Java NIO

          本文链接:https://www.haomeiwen.com/subject/tejlyxtx.html