【Netty】NIO 选择器 ( Selector ) 通道 ( Channel ) 缓冲区 ( Buffer ) 网络通信案例

简介: 【Netty】NIO 选择器 ( Selector ) 通道 ( Channel ) 缓冲区 ( Buffer ) 网络通信案例

文章目录

I . SelectionKey 简介

II . SelectionKey 事件简介

III . SelectionKey 常用 API 简介





I . SelectionKey 简介


1 . 通道注册给选择器 : 通道 ( Channel ) 注册给 选择器 ( Selector ) , 该通道就会纳入到该 选择器 ( Selector ) 管理范畴 , 选择器 ( Selector ) 可以监听通道的事件 ;


被注册的通道说明 : 这个 通道 ( Channel ) 即可以是 服务器套接字通道 ( ServerSocketChannel ) , 也可以是 套接字通道 ( SocketChannel ) ;



2 . 选择器真实类型 : 选择器 ( Selector ) 的 Selector 类是抽象类 , 其实例化的 真实类型是 WindowsSelectorImpl ;



3 . 选择器 ( Selector ) 管理 通道 ( Channel ) 的方式 : 当 通道 ( Channel ) 注册给 选择器 ( Selector ) 后 , 会返回 SelectionKey , 并将该 SelectionKey 放入 选择器 ( Selector ) 中的 HashSet<SelectionKey> keys 集合中 , 这个集合中存放了所有注册给该 选择器 ( Selector ) 的通道所代表的 SelectionKey ;



4 . 获取有事件发生的通道对应的 SelectionKey 集合 : 当 选择器 ( Selector ) 监听到有事件发生 , 此时只能监听到事件发生的个数 , 不知道具体的情况 ; 这就需要自己去 调用 选择器 ( Selector ) 的 selectedKeys() 方法 , 此时返回的是 Set<SelectionKey> 类型的集合 , 因为同事可能有多个通道有事件发生 , 这里可以一次性处理多个通道的事件 ;






II . SelectionKey 事件简介


SelectionKey 中的事件 , 就是 选择器 ( Selector ) 注册通道时 , 需要指明 , 监听这个通道的哪些事件 ;



SelectionKey 中定义了四种事件 : 数据读取 ( OP_READ ) , 数据写出 ( OP_WRITE ) , 连接 ( OP_CONNECT ) , 接受连接 ( OP_ACCEPT ) ;




1 . 接受连接 ( OP_ACCEPT ) 事件 :



① 适用场景 : 服务器端 服务器套接字通道 ( ServerSocketChannel ) 注册该事件给 选择器 ( Selector ) , 选择器 ( Selector ) 可以监听到客户端的连接请求 ;


② 代码示例 : 下面的代码作用是 , 将 ServerSocketChannel 通道的 SelectionKey.OP_ACCEPT 事件注册给 选择器 ( Selector ) , 当有客户端连接服务器的时候 , 就会触发 选择器 的监听方法 ;


//将 serverSocketChannel 通道注册给 选择器 ( Selector ), 这里注册连接事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);


③ OP_ACCEPT 常量原型 : 该常量定义在 SelectionKey.java 类中 , 该值的大小是 1 << 4 , 0b10000 ( 二进制 ) , 0x10 ( 十六进制 ) , 16 ( 十进制 ) ;

/**
 * Operation-set bit for socket-accept operations.
 *
 * <p> Suppose that a selection key's interest set contains
 * <tt>OP_ACCEPT</tt> at the start of a <a
 * href="Selector.html#selop">selection operation</a>.  If the selector
 * detects that the corresponding server-socket channel is ready to accept
 * another connection, or has an error pending, then it will add
 * <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its
 * selected-key&nbsp;set.  </p>
 */
public static final int OP_ACCEPT = 1 << 4;




2 . 读取数据 ( OP_READ ) 事件 :



① 适用场景 : 服务器端 套接字通道 ( SocketChannel ) 注册该事件给 选择器 ( Selector ) , 选择器 ( Selector ) 可以监听到客户端的 数据写入到服务器 , 也就是说 服务器端需要执行 读取数据 的工作 ;


② 代码示例 : 下面的代码作用是 , 将 SocketChannel 通道的 SelectionKey.OP_READ 事件注册给 选择器 ( Selector ) , 当有客户端上传数据的时候 , 就会触发 选择器 的监听方法 ;


//注册通道 : 将 SocketChannel 通道注册给 选择器 ( Selector )
//关注事件 : 关注事件时读取事件, 服务器端从该通道读取数据
//关联缓冲区 :
sc.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));


③ OP_READ 常量原型 : 该常量定义在 SelectionKey.java 类中 , 该值的大小是 1 << 0 , 0b1 ( 二进制 ) , 0x1 ( 十六进制 ) , 1 ( 十进制 ) ;


/**
 * Operation-set bit for read operations.
 *
 * <p> Suppose that a selection key's interest set contains
 * <tt>OP_READ</tt> at the start of a <a
 * href="Selector.html#selop">selection operation</a>.  If the selector
 * detects that the corresponding channel is ready for reading, has reached
 * end-of-stream, has been remotely shut down for further reading, or has
 * an error pending, then it will add <tt>OP_READ</tt> to the key's
 * ready-operation set and add the key to its selected-key&nbsp;set.  </p>
 */
public static final int OP_READ = 1 << 0;



3 . 写出数据 ( OP_WRITE ) 事件 :



① 适用场景 : 将通道 ( Channel ) 注册给 选择器 ( Selector ) , 注册该 写出数据 ( OP_WRITE ) 事件 , 如果选择器触发该事件 , 表示该 向该 通道 ( Channel ) 写出数据了 ;


② OP_WRITE 常量原型 : 该常量定义在 SelectionKey.java 类中 , 该值的大小是 1 << 2 , 0b100 ( 二进制 ) , 0x4 ( 十六进制 ) , 4 ( 十进制 ) ;


/**
 * Operation-set bit for write operations.
 *
 * <p> Suppose that a selection key's interest set contains
 * <tt>OP_WRITE</tt> at the start of a <a
 * href="Selector.html#selop">selection operation</a>.  If the selector
 * detects that the corresponding channel is ready for writing, has been
 * remotely shut down for further writing, or has an error pending, then it
 * will add <tt>OP_WRITE</tt> to the key's ready set and add the key to its
 * selected-key&nbsp;set.  </p>
 */
public static final int OP_WRITE = 1 << 2;


4 . 连接 ( OP_CONNECT ) 事件 :



① 适用场景 : 将通道 ( Channel ) 注册给 选择器 ( Selector ) , 注册该 连接 ( OP_CONNECT ) 事件 , 如果选择器触发该事件 , 表示该 发起网络 Socket 连接了 ;


② OP_WRITE 常量原型 : 该常量定义在 SelectionKey.java 类中 , 该值的大小是 1 << 3 , 0b1000 ( 二进制 ) , 0x8 ( 十六进制 ) , 8 ( 十进制 ) ;


/**
 * Operation-set bit for socket-connect operations.
 *
 * <p> Suppose that a selection key's interest set contains
 * <tt>OP_CONNECT</tt> at the start of a <a
 * href="Selector.html#selop">selection operation</a>.  If the selector
 * detects that the corresponding socket channel is ready to complete its
 * connection sequence, or has an error pending, then it will add
 * <tt>OP_CONNECT</tt> to the key's ready set and add the key to its
 * selected-key&nbsp;set.  </p>
 */
public static final int OP_CONNECT = 1 << 3;






III . SelectionKey 常用 API 简介


1 . 获取 NIO 三大组件 选择器 ( Selector ) , 通道 ( Channel ) , 缓冲区 ( Buffer ) 方法 :



① 获取 选择器 ( Selector ) : Selector selector() , 调用该方法获取对应的 选择器 ( Selector ) ;


② 获取 通道 ( Channel ) : SelectableChannel channel() , 调用该方法 获取对应绑定的 通道 ( Channel ) ;


③ 获取 缓冲区 ( Buffer ) : Object attach(Object ob) , 调用该方法 获取 注册的 通道 ( Channel ) 对应的 缓冲区 ( Buffer ) ;


④ 代码示例 : 这是上一篇博客中 NIO 通信案例中的 服务器端的部分代码 , 涉及到了获取 通道 和 缓冲区 操作 ;


//获取 通道 ( Channel ) : 通过 SelectionKey 获取
SocketChannel socketChannel = (SocketChannel) key.channel();
//获取 缓冲区 ( Buffer ) : 获取到 通道 ( Channel ) 关联的 缓冲区 ( Buffer )
ByteBuffer byteBuffer = (ByteBuffer) key.attachment();



2 . 事件相关的方法 :



① 设置或更改监听事件 : interestOps(int ops) , 设置 或 改变 选择器 ( Selector ) 关联的事件 ;


② 判定事件类型 :


是否是 OP_READ 事件 : boolean isReadable() ;

是否是 OP_WRITE 事件 : boolean isWritable() ;

是否是 OP_CONNECT 事件 : boolean isConnectable() ;

是否是 OP_ACCEPT 事件 : boolean isAcceptable() ;


目录
相关文章
|
2月前
|
编解码 分布式计算 网络协议
Netty高性能网络框架(一)
Netty高性能网络框架(一)
|
13天前
|
消息中间件 编解码 网络协议
Netty从入门到精通:高性能网络编程的进阶之路
【11月更文挑战第17天】Netty是一个基于Java NIO(Non-blocking I/O)的高性能、异步事件驱动的网络应用框架。使用Netty,开发者可以快速、高效地开发可扩展的网络服务器和客户端程序。本文将带您从Netty的背景、业务场景、功能点、解决问题的关键、底层原理实现,到编写一个详细的Java示例,全面了解Netty,帮助您从入门到精通。
48 0
|
2月前
|
Java
Netty BIO/NIO/AIO介绍
Netty BIO/NIO/AIO介绍
|
2月前
|
存储 机器人 Linux
Netty(二)-服务端网络编程常见网络IO模型讲解
Netty(二)-服务端网络编程常见网络IO模型讲解
|
3月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
121 0
|
3月前
|
存储 网络协议 Java
【Netty 神奇之旅】Java NIO 基础全解析:从零开始玩转高效网络编程!
【8月更文挑战第24天】本文介绍了Java NIO,一种非阻塞I/O模型,极大提升了Java应用程序在网络通信中的性能。核心组件包括Buffer、Channel、Selector和SocketChannel。通过示例代码展示了如何使用Java NIO进行服务器与客户端通信。此外,还介绍了基于Java NIO的高性能网络框架Netty,以及如何用Netty构建TCP服务器和客户端。熟悉这些技术和概念对于开发高并发网络应用至关重要。
74 0
|
4天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的知识,并提供一些实用的技巧和建议,帮助读者更好地保护自己的网络安全和信息安全。
|
3天前
|
安全 算法 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在当今数字化时代,网络安全和信息安全已经成为了全球关注的焦点。随着技术的发展,网络攻击手段日益狡猾,而防范措施也必须不断更新以应对新的挑战。本文将深入探讨网络安全的常见漏洞,介绍加密技术的基本概念和应用,并强调培养良好安全意识的重要性。通过这些知识的分享,旨在提升公众对网络安全的认识,共同构建更加安全的网络环境。
|
2天前
|
存储 安全 网络安全
云计算与网络安全:探索云服务、网络安全和信息安全的交汇点
在数字化时代,云计算已成为企业和个人存储、处理数据的关键技术。然而,随着云服务的普及,网络安全问题也日益凸显。本文将深入探讨云计算与网络安全的关系,分析云服务中的安全挑战,并提出相应的解决方案。同时,我们还将介绍一些实用的代码示例,帮助读者更好地理解和应对网络安全问题。
|
5天前
|
安全 算法 网络协议
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字时代,网络安全和信息安全已经成为了我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,帮助读者更好地了解网络安全的重要性和应对措施。通过阅读本文,您将了解到网络安全的基本概念、常见的网络安全漏洞、加密技术的原理和应用以及如何提高个人和组织的网络安全意识。
下一篇
无影云桌面