>>关于NIO

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

(1)Reactor模式
Reactor即反应器,就是我们将事件注册到Reactor中,当有相应的事件发生时,Reactor便会告知我们有哪些事件发生了,我们再根据具体的事件去做相应的处理。在NIO里主要是Selector多路复用模型。

(2)BIO(同步阻塞IO)和NIO的区别

BIO在调用read/write的时候会阻塞线程,也就是就算某个时刻你的socket并没有数据需要传输,
但是你的socket线程却仍然会被阻塞在read/write方法上,所以BIO是一个socket连接一个线程。
NIO与BIO不同,它主要依靠事件监听反应器进行工作,一个监听器可以监听好几个socket连接,只有在socket有事件发生(如读写数据,连接到达等)的时候才进行事件分发,
开启线程去处理事件(一个请求一个线程),所以在高并发的时候NIO是优于BIO的。
并且NIO有了缓冲区的概念,不管是File IO还是Socket IO都是在和Buffer相互读取,
NIO可以先将通道数据读到缓冲区中再进行操作,避免了逐字节或逐行读取的性能开销。

NIO主要可以分为四个模块,分别是Buffer(数据缓冲区),Channel(数据通道),Selector(监听器),Charset(字符集)

>>Buffer(数据缓冲区)

缓冲区(Buffer)就是在内存中预留指定字节数的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区;

在Java NIO中,缓冲区的作用也是用来临时存储数据,可以理解为是I/O操作中数据的中转站。
缓冲区直接为通道(Channel)服务,写入数据到通道或从通道读取数据。

java.nio.Buffer是一个抽象类,直接继承Buffer的缓冲区类有七种:
ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,LongBuffer,ShortBuffer。
其中MappedByteBuffer继承ByteBuffer,专门用于内存映射,可以处理大文件读写等。

Buffer有四个属性,

private int mark = -1;
private int position = 0;
private int limit;
private int capacity; 

Capacity 容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变
Limit 上界,缓冲区中当前数据量
Position 位置,下一个要被读或写的元素的索引
Mark 标记,调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置即position=mark

具体的操作方法主要有clear(清空缓冲区),flip(把缓冲区状态改为写状态),put(向缓冲区写入数据),get(从缓冲区读取数据)。

>>Channel(数据通道)

Channel相当于BIO里面的Stream(数据流),但Channel与Stream不同,Channel是双向的,
可以向通道两边传输数据,而不用像BIO那样要专门建立一个输入流和一个输出流。
I/O可以分为文件IO和流IO,那么Channel对应的就可以分为文件通道(FileChannel)和流通道(流通道就是套接字通道,SocketChannel),NIO中Channel接口主要的通道实现类有以下几种:

FileChannel 文件通道,用于操作文件I/O
SocketChannel 套接字通道,用于TCP协议,客户端连接服务器后,
服务器和客户端都会有一个SocketChannel,就可以互相发送数据了
ServerSocketChannel 服务器套接字通道,用于TCP连接响应客户端连接

通道可以以阻塞(blocking)或非阻塞(non-blocking)模式运行,阻塞模式会一直等待某个操作直到返回结果;非阻塞不会一直等待,要么返回null,要么返回执行完的结果。

>>Selector(监听器)

Selector是NIO的核心,

(1)选择器的创建
java.nio.channels.Selector提供了一系列的静态方法,可以直接调用,

//创建选择器
Selector sle =Selector.open();

Selector(选择器)提供了下面方法:

open():打开一个选择器
isOpen():检查一个选择器实例是否打开
provider():返回一个SelectorProvider
keys():返回注册键集合
selectedKeys():返回已选择键集合
selectNow():立刻执行选择,非阻塞,若没有已准备好的通道则立即返回0
select(long timeout):执行选择,超过指定毫秒数则返回
select():执行选择,会一直阻塞直到有准备就绪的通道
wakeup():停止选择
close():关闭选择器

(2)轮询获取注册到选择器中通道感兴趣的操作

//创建选择器
			Selector sle =Selector.open();
			//创建socket服务器通道
			ServerSocketChannel socketChn=ServerSocketChannel.open();
			/**
			 * 绑定端口
			 * InetSocketAddress是SocketAddress的子类
			 */
			socketChn.socket().bind(new InetSocketAddress(65535));
			//设置是否非阻塞
			socketChn.configureBlocking(false);
			/**
			 * 将通道注册到选择器,指定通道兴趣是等待接收连接
			 * NIO中定义了4中可选择操作:OP_READ(读)、OP_WRITE(写)、OP_CONNECT(连接)、OP_ACCEPT(接受),
			 * 这些常量在SelectionKey中定义
			 */
			SelectionKey key = socketChn.register(sle, SelectionKey.OP_ACCEPT);
			//使用while循环轮询获取注册到选择器中通道感兴趣的操作
			while(true){
				//选择注册到选择器中通道感兴趣的键,此方法是阻塞的,直到有感兴趣的事件发生
//				int n=sle.select();
				//立即查询,非阻塞
				int n=sle.selectNow();
				 Iterator<SelectionKey> iter = sle.selectedKeys().iterator();
			        while (iter.hasNext()) {
			            SelectionKey keyy = iter.next();
			            iter.remove();
			            // ......
			        }
			    	//close()方法可以关闭选择器
					sle.close();
			    }  

(3)poll和epoll 选择器的内部实现

选择器为通道服务,通道事先告诉选择器:“我对某些事件感兴趣,如可读、可写等“,

选择器在接受了一个或多个通道的委托后,开始选择工作,它的选择工作就完全交给操作系统,linux下即为poll或epoll。

>>Charset(字符集)

主要是指java.nio.charset包下的一系列工具类,

NIO提供了CharsetDecoder和CharsetEncoder进行字符集的编码和解码。

Netty网络编程之NIO概览与简单应用的更多相关文章

  1. 【Java】网络编程之NIO

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

  2. 解锁网络编程之NIO的前世今生

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) NIO 内容概览: NIO 网络编程模型 NIO 网络编程详解 NIO 网络编程实战 NIO 网络编程缺 ...

  3. 网络编程之NIO

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

  4. java 网络编程之TCP通信和简单的文件上传功能

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  5. 网络编程4 网络编程之FTP上传简单示例&socketserver介绍&验证合法性连接

    今日大纲: 1.FTP上传简单示例(详细代码) 2.socketserver简单示例&源码介绍 3.验证合法性连接//[秘钥加密(urandom,sendall)(注意:中文的!不能用)] 内 ...

  6. java 网络编程之UDP通信和简单的群聊程序

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  7. linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)

    单客户端和服务端的通信(基于UDP)   代码 服务端代码socket3.c #include<sys/types.h> #include<sys/socket.h> #inc ...

  8. Python网络编程之TCP套接字简单用法示例

    Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...

  9. 网络编程之TCP编程

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

随机推荐

  1. WC总结

    去了人生中第一次全国WC,在四川绵阳南山中学举行,去了这么一次,感受颇多,不忍心白白地让时间流逝,于是写篇随笔记录一下. 全程,共计8天. [第1天] 签到,拿餐票,看了看讲义,觉得要狗带. 开营仪式 ...

  2. Android之NetworkOnMainThreadException异常

    看名字就应该知道,是网络请求在MainThread中产生的异常 先来看一下官网的解释: Class Overview The exception that is thrown when an appl ...

  3. 汉诺塔(河内塔)算法 ----C语言递归实现

    汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子, 在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺 ...

  4. 18.1---不用加号的加法(CC150)

    1,自己写的又长又臭的代码,也能AC,但是太丑了.主要是通过二进制来算. public static int addAB(int a, int b){ int res = 0; String str1 ...

  5. js的工作原理

    JavaScript就是所谓的客户端脚本语言,是一种在互联网浏览器(浏览器也称为Web客户端,因为它连接到Web服务器上,以下载页面)内部运行的计算机编程语言. 也就是说,如果一个网页里有js代码,那 ...

  6. ADO.NET和ADO.NET Entity Framework

    ADO.NET 3.0 用于访问和操作数据的两个主要组件是 .NET Framework 数据提供程序和 DataSet. .NET Framework 数据提供程序 .NET Framework 数 ...

  7. Context.managedQuery()和context.getContentResolver()获取Cursor关闭注意事项

    在获取图片缩略图时,获取游标并进行相关的操作. Cursor cursor = context.getContentResolver().query(MediaStore.Images.Thumbna ...

  8. 转:C++编程隐蔽错误:error C2533: 构造函数不能有返回类型

    C++编程隐蔽错误:error C2533: 构造函数不能有返回类型 今天在编写类的时候,出现的错误. 提示一个类的构造函数不能够有返回类型.在cpp文件里,该构造函数定义处并没有返回类型.在头文件里 ...

  9. HBase集成Zookeeper集群部署

    大数据集群为了保证故障转移,一般通过zookeeper来整体协调管理,当节点数大于等于6个时推荐使用,接下来描述一下Hbase集群部署在zookeeper上的过程: 安装Hbase之前首先系统应该做通 ...

  10. 小项目特供 简易迷宫(基于Java)

    明天返校,于是昨天和今天简单熟系了一下JAVA的GUI,做了一个简易的迷宫小游戏(暂时没有时间实现随机迷宫及多关卡,仅供学习) 源码及运行文件(提供JRE8):链接:简易迷宫 密码:hy8v