Netty网络编程之NIO概览与简单应用
>>关于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概览与简单应用的更多相关文章
- 【Java】网络编程之NIO
简单记录 慕课网-解锁网络编程之NIO的前世今生 & 一站式学习Java网络编程 全面理解BIO/NIO/AIO 内容概览 文章目录 1.[了解] NIO网络编程模型 1.1.NIO简介 1. ...
- 解锁网络编程之NIO的前世今生
个人博客网:https://wushaopei.github.io/ (你想要这里多有) NIO 内容概览: NIO 网络编程模型 NIO 网络编程详解 NIO 网络编程实战 NIO 网络编程缺 ...
- 网络编程之NIO
传统的BIO(Blocking IO)的缺点: 1.基于阻塞式IO建立起来的,导致服务端一直阻塞等待着客户端发起请求,如果客户端不发起,服务端的的业务线程会一直存. 2.弹性伸缩能力差,线程数和客户端 ...
- java 网络编程之TCP通信和简单的文件上传功能
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 网络编程4 网络编程之FTP上传简单示例&socketserver介绍&验证合法性连接
今日大纲: 1.FTP上传简单示例(详细代码) 2.socketserver简单示例&源码介绍 3.验证合法性连接//[秘钥加密(urandom,sendall)(注意:中文的!不能用)] 内 ...
- java 网络编程之UDP通信和简单的群聊程序
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)
单客户端和服务端的通信(基于UDP) 代码 服务端代码socket3.c #include<sys/types.h> #include<sys/socket.h> #inc ...
- Python网络编程之TCP套接字简单用法示例
Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...
- 网络编程之TCP编程
网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...
随机推荐
- 剑指Offer 替换空格
题目描述 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 思路: 替换空格,先遍历一遍记 ...
- gulp学习笔记2-安装
安装nodejs -> 全局安装gulp -> 项目安装gulp以及gulp插件 -> 配置gulpfile.js -> 运行任务 1.去nodejs官网安装nodejs 2. ...
- Android圆角矩形创建工具RoundRect类
用于把普通图片转换为圆角图像的工具类RoundRect类(复制即可使用): import android.content.Context; import android.graphics.Bitmap ...
- Java实现读取文件夹下(包括子目录)所有文件的文件名
在编程的过程中,经常会用到对文件的读写操作等.比如,找出某一个文件夹下的所有文件名等. 下面的程序给出了,获取某一给定文件夹下所有文件的绝对路径的程序.可以作为某一个模块,在需要的时候直接使用. pa ...
- python入门教程链接
python安装 选择 2.7及以上版本 linux: 一般都自带 windows: https://www.python.org/downloads/windows/ mac os: https:/ ...
- python对象的生命周期
引言 碰到以下问题: 代码1: from Tkinter import * root = Tk() photo = PhotoImage(file=r'E:\workspace\python\111. ...
- php上传文件大小限制修改
打开php.ini 1.最大上传文件大小: upload_max_filesize=2M 改成自己需要的大小 2.最大post大小: post_max_size=2M 改成自己需要的大小,第二个一般比 ...
- 【实例】html5-canvas中实现背景图片的移动
本例来自于<HTML5 Canvas核心技术 图形.动画与游戏开发> 在线演示 (图有点多,请多刷新几次) 本例还有一点代码不理解,我用注释和问号标注出来了,有大神看到求解答,谢谢 本例子 ...
- 【Nginx】nginx 代理 Haproxy 怎么设置?
由于Haproxy是通过 url 正则匹配 识别 的,nginx代理到 haproxy需要设置 proxy_set_header Host 为 haproxy的目标 url 直接上配置 upstrea ...
- Java中 final static super this instanceof 关键字用法
一.final关键字 final可以修饰变量.方法及类: 1.当定义一个final变量时,jvm会将其分配到常量池中,其所修饰的对象只能赋值一次,对基本类型来说是其值不可变,引用类型(包括作为函数形参 ...