个人博客网:https://wushaopei.github.io/    (你想要这里多有)

NIO 内容概览:

  • NIO 网络编程模型
  • NIO 网络编程详解
  • NIO 网络编程实战
  • NIO 网络编程缺陷

一、NIO网络编程模型

1、编程模型定义

NIO :  又叫Non-blocking I/O或New I/O;全新的输入输出标准库;

做为原始I/O的补充,为了高性能和高并发的场景使用。

模型:对事物共性的抽象;

编程模型:对编程共性的抽象;

2、BIO网络模型

  • 服务端启动,开始建立监听客户端的连接请求;
  • 客户端启动,向服务器端发起建立连接请求;
  • 服务器在收到客户端的请求后,将会创建一个新的线程;
  • 服务端新创建的线程会与客户端建立socket连接,用于响应客户端的请求,通知客户端连接建立成功,你随时可以给我发送数据。
  • 服务器端处理完客户端的请求之后,就会处于等待状态,等待客户端再次发起请求

服务端为每一个客户端建一个线程,一旦客户端请求过多,服务端线程数量也会增多,服务端压力增大。

3、BIO网络模型缺点

  • 阻塞式I/O模型,会导致服务器端的业务线程会因阻塞IO的问题一直阻塞等待客户端发起请求,如果客户端不发起请求,服务端的业务线程会一直存在,就会耗费大量系统资源

  • 弹性伸缩能力差:服务器端的线程数与客户端的个数呈1比1的关系

  • 多线程耗资源 : 每一个线程都会对CPU的调度资源进行占用,一旦占用而不释放,则会导致资源的紧缺、甚至系统服务的异常宕机

4、NIO网络模型猜想

基于非阻塞 I/O , 设计应对高并发场景编程模型

图解分析:NIO架构中,客户端的个数与服务器端的线程数呈M:1的关系

5、NIO 网络模型

第一步:注册连接并提供服务:Selector 中初始化注册并建立连接事件,提供给Client建立连接的服务;client通过Selector连接与AcceptorHandler 发送创建客户端的连接,并又AcceptorHandler方法返回响应结果;同时该AcceptorHandler方法向Selector中注册可读事件(Client连接客户端成功后)

第二步:提供服务:client 发送请求,Selector中对注册状态及客户端可读性验证,正常情况下,已通过第一步,所以直接连接到处理器进行读写操作,根据需求执行业务逻辑,并响应给客户;

第三步:客户端连接可读,在向client响应客户端请求后,注册连接可读事件到Selector 中,所注册的是具体执行业务的Handler

6、NIO网络模型优化

  1. 非阻塞IO模型,服务器端提供一个单线程的selector来统一管理所有客户端接入的连接,并负责监听每个连接所关心的事件

  2. 弹性伸缩能力加强,服务器端一个线程处理所有客户端的连接请求,客户端的个数与服务器端的线程数呈M比1的关系

  3. 单线程节省资源,避免了线程的频繁创建和销毁,同时也避免了多个线程之间上下文的切换,提高了执行效率

二、NIO网络编程详解

NIO核心

  • Channel:通道
  • Buffer : 缓冲区
  • Selector : 选择器 或 多路复用器

1、NIO核心类之Channel

Channel 具有双向性、非阻塞性、操作唯一性。

channel是信息传输的通道,是jdk NIO中对输入输出方法的另一种抽象,类比IO中的流,与流不同之处在于,channel具有双向性,而流是单向传输的,一个流必须是InputStream或OutputStream的子类,而通道可以用于读写或二者同时进行。channel可以工作在非阻塞模式下,构成NIO的基础。在NIO中,操作channel的唯一方式是使用buffer,通过buffer操作channel,实现数据块的传输。

channel的实现:

  1. 文件类:FileChannel,用于对文件的读写
  2. UDP类:DatagramChannel, 用于UDP的数据读写
  3. TCP类:ServerSocketChannel/SocketChannel,用于TCP的数据读写

Socket的使用:

Channel的使用:

2、NIO核心类之Buffer

Buffer:缓冲区,它提供唯一与channel进行交互的方式,作用是读写channel中的数据。Buffer从本质上说是一块内存区域,它是一块可以写入数据,读取数据的内存。

Buffer的属性

Capacity:分配的buffer容量,一旦写入的最大字节数超过这个容量,需要将其清空之后,才能继续往里面写数据

Position:当前操作的位置,初始值为0,最大值:容量值-1

Limit:上限,写模式下等于Capacity,读模式下等于最多能读取的数据

Mark:标记,记录mark的位置,调用reset方法时position会回到mark的位置

Buffer的使用:

  /*
* 初始化长度为10的byte类型 buffer
*/
ByteBuffer.allocate(10);

  /*
* 向byteBuffer中写入三个字节
*/
byteBuffer.put("abc".getBytes(Charset.forName("UTF-8")));

  /*
* 将byteBuffer从写模式切换成读模式
*/
byteBuffer.flip():

  /*
* 将b先调用get方法读取下一个字节
* 再调用reset方法将position重置到mark位置
*/
byteBuffer.get():
byteBuffer.reset();

  /*
* 调用clear方法,将所有属性重置
*/
byteBuffer.clear();

3、NIO核心类之Selector

Selector 选择器/多路复用器

作用:I/O就绪选择

地位:NIO网络编程的基础

SelectionKey 选择键

四种就绪状态常量:连接就绪、接受就绪、读就绪、写就绪

Selector的使用:

最重要的应该就是代码片段3: 在这一步对就绪事件进行监听,如果一直不通过,就一直阻塞等待,直到有就绪事件发生,并注册通过检测有效,方才放行

4、NIO编程实现步骤

第一步:创建Selector

第二步:创建ServerSocketChannel,并绑定监听端口

第三步:将Channel设置为非阻塞模式

第四步:将Channel注册到Selector上,监听连接事件

第五步:循环调用Selector的select方法,检测就绪情况

第六步:调用selectedKeys方法获取就绪channel集合

第七步:判断就绪事件种类,调用业务处理方法

第八步:根据业务需要决定是否再次注册监听事件,重复执行第三步操作

码云:https://gitee.com/wushaopei/IO/tree/master/nio-chai-room

解锁网络编程之NIO的前世今生的更多相关文章

  1. 【Java】网络编程之NIO

    简单记录 慕课网-解锁网络编程之NIO的前世今生 & 一站式学习Java网络编程 全面理解BIO/NIO/AIO 内容概览 文章目录 1.[了解] NIO网络编程模型 1.1.NIO简介 1. ...

  2. 网络编程之NIO

    传统的BIO(Blocking IO)的缺点: 1.基于阻塞式IO建立起来的,导致服务端一直阻塞等待着客户端发起请求,如果客户端不发起,服务端的的业务线程会一直存. 2.弹性伸缩能力差,线程数和客户端 ...

  3. Netty网络编程之NIO概览与简单应用

    >>关于NIO Java NIO即Java Non-blocking IO(Java非阻塞I/O),是Jdk1.4之后增加的一套操作I/O工具包,又被叫做Java New IO. (1)R ...

  4. 网络编程之TCP编程

    网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...

  5. 网络编程之socket

    网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...

  6. [深入浅出WP8.1(Runtime)]网络编程之HttpClient类

    12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类 ...

  7. java网络编程之TCP通讯

    java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...

  8. python3网络编程之socketserver

    本节主要是讲解python3网络编程之socketserver,在上一节中我们讲到了socket.由于socket无法支持多用户和多并发,于是就有了socket server. socket serv ...

  9. 网络编程之UDP编程

    网络编程之UDP编程 UDP协议是一种不可靠的网络协议,它在通信的2端各建立一个Socket,但是这个Socket之间并没有虚拟链路,这2个Socket只是发送和接受数据的对象,Java提供了Data ...

随机推荐

  1. mysql中的读锁和写锁

    当mysql为一个表开启读锁的时候,其他进程包括进程本身没有权利去修改这张表的内容,也没有权利更新,但是可以读取表里面的内容 如下例子 给表上读锁 接着更新一下,显示被锁了 释放锁并插入数据 写锁 查 ...

  2. Coursera课程笔记----计算导论与C语言基础----Week 9

    C语言中的控制成分(Week 9) 计算机程序的基本结构 任何具有单入口单出口的程序,都可以用顺序结构.分支结构.循环结构来表达 分支语句 在执行if语句前,先对表达式求解 if()内可以是任意的数值 ...

  3. 【Kafka】数据分区策略

    数据分区策略 四种策略 一.指定分区号,数据会直接发送到所指定的分区 二.没有指定分区号,指定了数据的key,可以通过key获取hashCode决定数据发送到哪个分区 三.都没有指定的话,会采取rou ...

  4. 内网穿透访问Vue项目的时候出现Invalid Host header解决办法

    适用场景: 在本地的Vue-cli3项目, 需要其他人浏览. 如果没有外网的服务器, 可以把自己的电脑当做服务器. 这时候需要外网的人能访问到自己的电脑. Mac内网穿透工具:natapp Inval ...

  5. 放大镜功能 JS原生写法

    ********** 希望对大家帮助 我会继续努力的 如果有不对的地方请大家帮忙指出****** 1 [JS 代码] <script> var oBox = document.getEle ...

  6. ES6,ES7,ES8 常用特性总结

    一. ES6(ES2015) 1. 变量 let 和常量 const var 的问题 可以重复声明,没有报错和警告 无法限制修改 没有块级作用域, { } let 和 const 不能重复声明 都是块 ...

  7. Sentinel源码解析一(流程总览)

    引言 Sentinel作为ali开源的一款轻量级流控框架,主要以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度来帮助用户保护服务的稳定性.相比于Hystrix,Sentinel的设计更加简 ...

  8. 横向滚动div

    <div id="shelf"> <div class="books"><div> <div class=" ...

  9. 王玉兰201771010128《面象对象程序设计(Java)》第九周学习总结

    第一部分:理论基础部分总结: 一:(1)异常:在程序的执行过程中所发生的异常事件,它中断指令的正常执行. 常见的几种错误:A:用户输入错误:B:设备错误;硬件出错:C:物理限制:磁盘满了,可用存储空间 ...

  10. PAT-1058 A+B in Hogwarts (进制转换)

    1058. A+B in Hogwarts If you are a fan of Harry Potter, you would know the world of magic has its ow ...