个人博客网: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. uniapp滚动监听元素

    鸽了这么久,一晃2个月过去了.自考+上班没时间记录. 前不久看到移动官网上的时间轴效果,看起来不错,我也来试着做一下. 需要元素滚动到视野内加载动画. 插件地址 https://ext.dcloud. ...

  2. 近期总结的一些Java基础

    1.面向过程:当需要实现一个功能的时候,每一个过程中的详细步骤和细节都要亲力亲为. 2.面向对象:当需要实现一个功能的时候,不关心详细的步骤细节,而是找人帮我做事. 3.类和对象的关系:   a-类是 ...

  3. FOC 电流采样为什么不准?你忽略了这个细节

    文章目录 1 引言 2 延迟类型及典型时间 3 延迟源详细分析 3.1PWM死区时间插入 3.2 光耦延迟和预驱动器延迟 3.3晶体管开关延迟 3.4其他延迟 4 结语 在电机驱动的FOC控制开发过程 ...

  4. 设计模式之GOF23装饰模式

    装饰模式decorator 作用: -动态的为一个对象增加新功能 -装饰模式是一种用于代替继承的技术,无需通过增加子类就能扩展对象的新功能,适用对象的组合关系代替继承关系,更加灵活,同时避免类型体系的 ...

  5. 可能会导致.NET内存泄露的8种行为

    原文连接:https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/作者 Michael Shpilt.授权翻译,转载请保 ...

  6. DIV+CSS布局的优势和弊端

    DIV+CSS的优势1.符合W3C标准.这保证您的网站不会因为将来网络应用的升级而被淘汰.2.对浏览者和浏览器更具亲和力.由于CSS富含丰富的样式,使页面更加灵活性,它可以根据不同的浏览器,而达到显示 ...

  7. Apache自定义404

    先用命令找到httpd.conf文件在哪 find -name 'httpd.conf' 默认配置文件: vim /etc/httpd/conf/httpd.conf 然后找到项目的路径 <Di ...

  8. django之CORS跨域请求

    对于想要利用django框架实现前后端分离,首要的问题是解决跨域请求的问题,什么是跨域请求?简单来说就是当前发起的请求的域与该请求指向的资源所在的域不一致.当协议+域名+端口号均相同,那么就是同一个域 ...

  9. Django之forms.ModelForm

    通常在Django项目中,我们编写的大部分都是与Django 的模型紧密映射的表单. 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中. 在这种情 ...

  10. Django认证系统之自带auth_user表操作

    Django自带auth_user表操作: views.py from django.contrib  import  auth#引入auth模块 from django.contrib.auth.m ...