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

简介:

1.关于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(字符集)

2.Buffer(数据缓冲区)

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

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

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


Buffer有四个属性,

1
2
3
4
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(从缓冲区读取数据)。

3.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,要么返回执行完的结果。


4.Selector(监听器)

Selector是NIO的核心,

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//创建选择器
             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。

5.Charset(字符集)

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

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

 



本文转自邴越博客园博客,原文链接:http://www.cnblogs.com/binyue/p/3857911.html,如需转载请自行联系原作者

相关文章
|
6月前
|
监控 前端开发 安全
Netty 高性能网络编程框架技术详解与实践指南
本文档全面介绍 Netty 高性能网络编程框架的核心概念、架构设计和实践应用。作为 Java 领域最优秀的 NIO 框架之一,Netty 提供了异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。本文将深入探讨其 Reactor 模型、ChannelPipeline、编解码器、内存管理等核心机制,帮助开发者构建高性能的网络应用系统。
421 0
|
编解码 分布式计算 网络协议
Netty高性能网络框架(一)
Netty高性能网络框架(一)
|
10月前
|
消息中间件 缓存 网络协议
Netty基础—4.NIO的使用简介
本文详细介绍了Java NIO(New Input/Output)的核心概念与编程模型。首先,讲解了Buffer缓冲区的作用及4个核心概念:capacity、limit、position、mark,并通过Direct模式创建的Buffer示例展示了其高性能特点。接着,分析了Channel通道的概念,说明其与Buffer的关系以及FileChannel在文件读写中的应用,包括顺序写、随机写和多线程安全特性。 随后,对比了BIO(Blocking IO)编程模型的局限性,如线程资源耗尽问题,引出伪异步IO编程的改进方案,但指出其仍存在级联故障风险。进一步探讨了长连接与短连接的区别及其实现代码。
|
10月前
|
弹性计算 网络协议 Java
Netty基础—2.网络编程基础二
本文介绍了网络编程的基本概念和三种主要模式:BIO(阻塞IO)、AIO(异步IO)和NIO(非阻塞IO)。BIO模型通过为每个客户端连接创建一个线程来处理请求,适合客户端较少的情况,但在高并发下性能较差。AIO模型通过异步IO操作,允许操作系统处理IO,适合高并发场景,但编码复杂且Linux支持有限。NIO模型通过Selector实现多路复用,适合高并发且性能要求高的场景。文章还详细介绍了NIO中的Buffer、Selector、Channel等核心组件,并提供了NIO的实战开发流程和代码示例。
|
10月前
|
监控 网络协议 Java
Netty基础—1.网络编程基础一
本文详细介绍了网络通信的基础知识,涵盖OSI七层模型、TCP/IP协议族及其实现细节。首先解释了OSI模型各层功能,如物理层负责数据通路建立与传输,数据链路层提供无差错传输等。接着探讨了TCP/IP协议,包括TCP和UDP的特点、三次握手与四次挥手过程,以及如何通过确认应答和序列号确保数据可靠性。还分析了HTTP请求的传输流程和报文结构,并讨论了短连接与长连接概念。 此外,解析了Linux下的IO模型,包括阻塞IO、非阻塞IO、IO复用(select/poll/epoll)、信号驱动IO和异步IO的特点与区别,强调了epoll在高并发场景下的优势及其水平触发和边缘触发两种工作模式。
|
10月前
|
网络协议 算法 Java
Netty基础—3.基础网络协议
本文详细梳理了计算机网络的基础知识,涵盖从物理层到应用层的各层协议及其功能。内容包括七层模型与四层模型对比、IP地址与子网划分、TCP三次握手及四次挥手过程、Socket编程原理、HTTP/HTTPS协议的工作机制等。同时深入探讨了Linux IO模型(阻塞、非阻塞、IO多路复用)及其应用场景,并分析了select、poll、epoll的区别。此外,还涉及Java IO读写的底层流程及同步异步、阻塞非阻塞的概念。这些知识点为理解网络通信和高性能服务器开发提供了全面的理论支持。
|
JSON 算法 Java
Nettyの网络聊天室&扩展序列化算法
通过本文的介绍,我们详细讲解了如何使用Netty构建一个简单的网络聊天室,并扩展序列化算法以提高数据传输效率。Netty的高性能和灵活性使其成为实现各种网络应用的理想选择。希望本文能帮助您更好地理解和使用Netty进行网络编程。
214 12
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
432 0
|
消息中间件 编解码 网络协议
Netty从入门到精通:高性能网络编程的进阶之路
【11月更文挑战第17天】Netty是一个基于Java NIO(Non-blocking I/O)的高性能、异步事件驱动的网络应用框架。使用Netty,开发者可以快速、高效地开发可扩展的网络服务器和客户端程序。本文将带您从Netty的背景、业务场景、功能点、解决问题的关键、底层原理实现,到编写一个详细的Java示例,全面了解Netty,帮助您从入门到精通。
2351 0