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

一、什么是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编程服务端步骤:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351