美文网首页Netty框架源码分析
4.Netty框架-网络IO编程模板(NIO编程模型)

4.Netty框架-网络IO编程模板(NIO编程模型)

作者: 还算年轻 | 来源:发表于2020-08-06 10:23 被阅读0次

    一、什么是NIO? 与BIO有哪些区别?

    1.什么是NIO?

            1、NIO = Selector+Channel+Buffer=构建Reactor模型。

            2、非阻塞IO,对应的IO模型是 多路复用IO。

           NIO: 同步非阻塞式IO,服务器实现模式为多个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 

            NIO 是一种同步非阻塞的 IO 模型。

            1)同步是指线程(多路复用器)不断轮询 IO 事件是否就绪,非阻塞是指线程在等待 IO 的时候,可以同时做其他任务。

            2)同步的核心就是 Selector,Selector 代替了线程本身轮询 IO 事件,避免了阻塞同时减少了不必要的线程消耗;

            3)非阻塞的核心就是通道和缓冲区,当 IO 事件就绪时,可以通过写道缓冲区,保证 IO 的成功,而无需线程阻塞式地等待。

            3、NIO = BUFFER + Selector  + Channel

            4、非阻塞= BUFFER + Channel;

            5、同步= Selector  ;

    2.NIO和BIO的区别?

            1.OIO面向流(字节/字符),NIO面向缓冲区。流:要求顺序,缓冲区不必、

            2.OIO是阻塞的

            3.OIO没有选择器,NIO有。

                NIO《-》OIO

                Channel《-》Socket

               ServerChanel《-》ServerSocket

            BIO(accept、io 都是阻塞):同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 

    二、NIO的基本组成:

            1.Channel:通道,互相通信的入口。

            2.Buffer:缓冲器,数据临时保存的地方。

            3.Selector:多路复用器,由系统提供,实现一个线程能够轮训多个通道的核心。

            1、Channel:

                FileChannel : 文件

                DatagramChanne : UDP

                SocketChannel : 与客户端建立产生的socket

                ServerSocketChannel : 服务端socket

        (1)FileChannel文件通道,用于文件的数据读写。

           //文件拷贝

            FileChannel inChannel = new FileInputStream(src).getChannel();

            FileChannel outChannel = new FileOutputStream(dst).getChannel();

            try {

                //从inChannel文件中读出count bytes ,并写入outChannel文件。

                inChannel.transferTo(0, inChannel.size(), outChannel);

            } finally {

                if (inChannel != null)

                    inChannel.close();

                if (outChannel != null)

                    outChannel.close();

            }

        (2)SocketChannel套接字通道,用于Socket套接字TCP连接的数据读写。

        (3)ServerSocketChannel服务器嵌套字通道(或服务器监听通道),允许我们监听TCP连接请求,为每个监听到的请求,创建一个SocketChannel套接字通道。、

        (4)DatagramChannel数据报通道,用于UDP协议的数据读写。

            2、BUFFER 缓冲器:
            BUFFER =  为什么说NIO是基于缓冲区的IO方式呢?因为,当一个链接建立完成后,IO的数据未必会马上到达,为了当数据到达时能够正确完成IO操作,在BIO(阻塞IO)中,等待IO的线程必须被阻塞,以全天候地执行IO操作。为了解决这种IO方式低效的问题,引入了缓冲区的概念,当数据到达时,可以预先被写入缓冲区,再由缓冲区交给线程,因此线程无需阻塞地等待IO。

            在 JDK 1. 4 中 新 加入 了 NIO( New Input/ Output) 类, 引入了一种基于通道和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆的 DirectByteBuffer 对象作为这块内存的引用进行操作,避免了在 Java 堆和 Native 堆中来回复制数据。

            2.1、通道的读取:就是将数据从通道读取到缓冲区中;通道的写入,就是将数据从缓冲区中写入到通道中。

            NIO的Buffer(缓冲区)本质上是一个内存块,既可以写入数据,也可以从中读取数据。

            NIO的Buffer类,是一个抽象类,位于java.nio包中,其内部是一个内存块(数组)。

            NIO的Buffer与普通的内存块(Java数组)不同的是:NIO Buffer对象,提供了一组更加有效的方法,用来进行写入和读取的交替访问。

            需要强调的是:Buffer类是一个非线程安全类。

            2.2、Buffer的属性:

               位置(position):当前缓冲区(Buffer)的位置,将从该位置往后读或写数据。

               容量(capacity):缓冲区的总容量上限。

               上限(limit):缓冲区的实际容量大小。

           2.3、Buffer的分类:(除Boolean)

               ByteBuffer、

               CharBuffer、

               DoubleBuffer、

               FloatBuffer、

               IntBuffer、

               LongBuffer、

               ShortBuffer、

                MappedByteBuffer

           2.4、Buffer的原理:

         默认初始:写模式:position=0,limit=capacity

        1.在写入模式下,position的值变化规则如下:

            (1)在刚进入到写模式时,position值为0,表示当前的写入位置为从头开始。

            (2)每当一个数据写到缓冲区之后,position会向后移动到下一个可写的位置。

            (3)初始的position值为0,最大可写值position为limit-1。当position值达到limit时,缓冲区就已经无空间可写了。

        2.flip()翻转后limit=position,position=0

        3.在读模式下,position的值变化规则如下:

            (1)当缓冲区刚开始进入到读模式时,position会被重置为0。

            (2)当从缓冲区读取时,也是从position位置开始读。读取数据后,position向前移动到下一个可读的位置。

            (3)position最大的值为最大可读上限limit,当position达到limit时,表明缓冲区已经无数据可读。

        数据写入后,如果要从缓冲区读取数据,这就要进行模式的切换,可以使用(即调用)flip翻转方法,将缓冲区变成读取模式。

       3、Selector多路复用器:

           依赖底层的epoll/select , JavaSelector选择器可以监听多个文件描述符(一个网络连接系统底层使用一个文件描述符表示),实现IO多路复用。

           实现IO多路复用,从具体的开发层面来说,首先把通道注册到选择器中,然后通过选择器内部的机制,可以查询(select)这些注册的通道是否有已经就绪的IO事件(例如可读、可写、网络连接完成等)。

    三、NIO的编程模板:

        1、NIO编程服务端时序图:

    2、NIO编程服务端步骤:

    相关文章

      网友评论

        本文标题:4.Netty框架-网络IO编程模板(NIO编程模型)

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