Netty 常见组件介绍
Netty 常见组件介绍
上篇文章Netty入门程序echo 基本包含了Netty常见的组件,本文分别介绍各个组件
- Bootstrap or ServerBootstrap
- EventLoop
- EventLoopGroup
- ChannelPipeline
- Channel
- Future or ChannelFuture
- ChannelInitializer
- ChannelHandler
Bootstrap vs ServerBootstrap
Bootstrap
Bootstrap 主要用于客户端的配置,它主要用于创建一个连接到远程服务器的客户端应用程序
它允许你设置以下内容
- EventLoopGroup
- Channel
- ChannelInitializer 用来配置新创建的通道的 ChannelPipeline。
Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("decoder", new StringDecoder());ch.pipeline().addLast("encoder", new StringEncoder());ch.pipeline().addLast(new ClientHandler());}});// 连接到服务器ChannelFuture f = b.connect(host, port).sync();
ServerBootstrap
ServerBootstrap 是专门用于配置和启动服务端通道的工具类。
它用于创建一个能够监听指定端口,接收客户端连接并处理客户端请求的服务器应用程序
ServerBootstrap还需要配置
childHandler 服务端会为每个客户端连接创建一个新的通道,childHandler方法用于添加处理这些客户端通道事件的ChannelHandler。
ServerBootstrap 需要两个 EventLoopGroup,一个用于接受连接
另一个用于处理 IO读写操作,而Bootstrap只需要指定一个EventLoopGroup用于处理IO读写操作
EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("decoder", new StringDecoder());ch.pipeline().addLast("encoder", new StringEncoder());ch.pipeline().addLast(new ServerHandler());}});ChannelFuture f = b.bind(port).sync();
Channel
Channel 在 Netty 中是对网络 I/O 操作的抽象。它代表了一个网络连接或者通信管道,可以是服务器端用于监听客户端连接的通道,也可以是客户端用于连接服务器的通道。
- NioSocketChannel
基于 Java NIO 的 Socket 通道,主要用于客户端建立 TCP 连接。前面Bootstrap客户端代码片段使用的就是NioSocketChannel
- NioServerSocketChannel
同样基于 Java NIO,用于服务器端监听 TCP 端口,等待客户端的连接请求。前面ServerBootstrap代码片段使用的就是NioSocketChannel
- EpollSocketChannel 和 EpollServerSocketChannel(适用于 Linux)
这两种通道是基于 Linux 的 epoll 机制实现的。
EpollSocketChannel用于客户端连接,EpollServerSocketChannel用于服务器监听
- OioSocketChannel 和 OioServerSocketChannel(基于旧的阻塞 I/O)
这是基于传统的阻塞式 I/O 实现的通道,使用的比较少,通常我们使用NIO,都使用Netty,还用阻塞IO,小编实在编不出有什么合适的理由。
ChannelPipeline
ChannelPipeline 是 Netty 中的一个核心组件,它是一个ChannelHandler 的责任链,负责处理所有的入站事件(读)和出站事件(写)。 无论服务端还是客户端都可能要处理读写事件,因为本质建立在TCP链接基础上,是全双工的。
ChannelPipeline无论在服务端还是客户端,它的设置都非常重要。
ChannelPipeline 包含着一系列的 ChannelHandler,服务端/客户端按照ChannelHandler顺序来处理 IO 事件,它的顺序非常重要。
事件处理顺序
责任链中隐含两个Handler,一个Header,一个是Tail,这两个非常重要,本文先点到为止。
加上Header和Tail用户向ChannelPipeline中添加的ChannelHandler1,ChannelHandler2,…,ChannelHandlerN ; 按顺序处理出站/入站事件。
入站事件顺序
入站事件从 ChannelPipeline 的头部开始,向尾部传播
Header -> ChannelHandler1 -> ChannelHandler2 -> … -> ChannelHandlerN -> Tail
出站事件顺序
出站事件则从ChannelPipeline尾部开始,向头部传播。
Tail -> ChannelHandlerN -> … -> ChannelHandler2 -> ChannelHandler1 -> Header
只有理解了ChannelPipeline的处理顺序,我们才能正确的设置责任链上 ChannelHandler,才能正确的处理对应事件。
ChannelInitializer
ChannelInitializer 是 Netty 中一个非常重要的组件, 它就像是一个 ChannelPipeline 的构建器
ChannelFuture
jdk线程池异步执行需要返回结果的 通常返回的是Future,
ChannelFuture 接口继承 Future,
ChannelFuture 是 Netty 中用于表示一个异步操作结果的接口。在 Netty 中,许多 I/O 操作(如连接建立、数据写入、绑定端口等)都是异步执行的。
ChannelHandler
ChannelHandler 是 Netty 中用于处理 Channel 事件的核心组件。它是一个接口,定义了一系列方法来处理各种网络 I/O 事件,
如数据读取、写入、连接建立和关闭等。可以把 ChannelHandler 看作是一个事件处理器
-
ChannelInboundHandler:
处理入站事件,如连接建立、数据接收、异常捕获等。
常见实现:SimpleChannelInboundHandler, ChannelInboundHandlerAdapter -
ChannelOutboundHandler:
处理出站事件,如绑定、连接、写入数据等。
常见实现:ChannelOutboundHandlerAdapter -
ChannelDuplexHandler:
同时处理入站和出站事件。
常见实现:ChannelDuplexHandler
上面列的几个类比较底层,Netty 内置了许多ChannelHandler ,如果使用Netty开发某些功能肯定会打交道,我们只需要专学处理消息的读写即可。以下列举几个典型的后续大部分都会接触。
- ByteToMessageDecoder
它是一个抽象类,它实现了 ChannelInboundHandler 接口,底层将数据读到ByteBuf中,我们需要将ByteBuf 转换为业务对象,再传递给后续处理器处理。
与之相对应的是MessageToByteEncoder ,将业务消息对象编码为"ByteBuf",再发送给客户端(出站事件)
StringDecoder 和 StringEncoder 就是对应的实现类。 我们基于ByteToMessageDecoder也能实现内置的处理器的能力
public class MyByteToMessageDecoder extends ByteToMessageDecoder {@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {msg = doDecode(in);out.add(msg);}}
其他高级的内置处理器,我们在处理半包,粘包问题可以结合使用。
- DelimiterBasedFrameDecoder
基于分隔符的解码器,用于处理以特定字符或字符序列分隔的消息。适用于消息以特定字符分隔的场景。 能够处理TCP 半包问题
- LineBasedFrameDecoder
基于行的解码器,用于处理以换行符分隔的消息。适用于消息以换行符分隔的场景。可以看成是特殊的基于分隔符的解码器
- FixedLengthFrameDecoder
固定长度的帧解码器,用于处理固定长度的消息。适用于消息长度固定的场景。能够处理TCP 半包问题
总结
Netty 组件看上去很多,实际上我们通常只需要关注 消息解码、编码 和读写事件的处理,这也是选择Netty 原因,简单同时兼顾性能。
相关文章:

Netty 常见组件介绍
Netty 常见组件介绍 上篇文章Netty入门程序echo 基本包含了Netty常见的组件,本文分别介绍各个组件 Bootstrap or ServerBootstrapEventLoopEventLoopGroupChannelPipelineChannelFuture or ChannelFutureChannelInitializerChannelHandler Bootstrap vs ServerBo…...

高频电子线路---倍频器与振荡器
目录 倍频电路原理 丙类倍频器原理电路 问题: 提升滤波方法: 导通角 振荡器 振荡器基本工作原理 首先是怎么维持 那么如何振荡呢? 思考题: 组成要素 振荡器的起振条件 平衡条件 要点提示 稳定条件 振幅平衡 硬激励起振时: 稳定条件 相位平衡 倍频电路原理 简单原理 : …...

删除 git submodule
直接运行下面命令即可: git rm <path-to-submodule>然后提交修改即可。 但是,还有一个小问题:上面命令只是将 submodule 的代码目录删除了。 以下痕迹还存在你的仓库中: .gitmodule 中关于该 submodule 的信息.git 目录…...

el-table 多选默认选中(根据返回的id给数据加默认选中状态)
前言 el-table是我们最常用的展示数据的方式,但是有时候需要用到多选来选择数据,新增数据的时候还好,选中状态都是正常的,但是修改就遇到问题,需要对这个已经选择过的数据加上默认的选中状态,本次就是解决…...

境外网站翻译之自由职业
Polls Do you use AI tools (e.g ChatGPT, Midjourney, Github Copilot) as part of your work? 你在工作中会使用人工智能工具(如 ChatGPT、Midjourney、Github Copilot)吗? Yes, as an assistant 是的,作为一种辅助工具。 Y…...

批量图片转PDF文件的多种方法详解
要将批量图片转换为PDF文件,可以使用多种方法,包括使用在线工具、桌面应用程序或编程语言。以下是几种常见的方法: 方法一:使用在线工具 选择工具:搜索“图片转PDF”在线工具,如 Smallpdf、ILovePDF 等。…...

Web服务器(理论)
目录 Web服务器www简介常见Web服务程序介绍:服务器主机主要数据浏览器 网址及HTTP简介URLhttp请求方法:2.3 HTTP协议请求的工作流程: www服务器的类型静态网站动态网站 快速安装Apache安装准备工作httpd所需目录主配置文件 nignx安装1、安装2、准备工作 …...

js:()=>(,);()的作用:明确表达式的边界。
()>{表达式1;表达式2;表达式3;... return 结果} 等同于 ()>(表达式1,表达式2,表达式3,... 结果) 例子: const strarr [a, b, c];const result strarr.reduce((acc, curr) > {(acc[curr] 1);console.lo…...

RSI 5G通信技术中用于标识小区的特定参数
RSI是指在5G通信技术中用于标识小区的特定参数,全称为Radio Subframe Indicator(无线子帧指示符)。在原文的上下文中,RSI被用来确保相邻小区间有足够的间隔,避免由于RSI冲突导致用户设备(UE)随机…...

JavaScript中的闭包、递归问题
一、函数定义和调用 1.函数的定义方式 方式一 函数声明方式 function 关键字(命名函数) function fn(){}方式二 函数表达式(匿名函数) var fn function(){}方式三 new Function() var f new Function(a,b,console.log(a b););//语法 var fn new Fu…...

【青牛科技】GC4938替代A4938/Allegro在水泵、筋膜枪、吸尘器和电动工具中的应用
随着技术的不断进步,电机驱动控制器在各类电动设备中的应用越来越广泛。GC4938作为一种新型的电机驱动控制器,逐渐被视为A4938/Allegro的替代品。在这篇文章中,我们将探讨GC4938在水泵、筋膜枪、吸尘器和电动工具等设备中的应用优势和特点。 …...

基于yolov5的输电线,电缆检测系统,支持图像检测,视频检测和实时摄像检测功能(pytorch框架,python源码)
更多目标检测和图像分类识别项目可看我主页其他文章 功能演示: yolov5,输电线(线缆)检测系统,系统既支持图像检测,也支持视频和摄像实时检测【pytorch框架】_哔哩哔哩_bilibili (一)简介 基于yolov5的输…...

uniapp下载文件的方案,包括H5,App方案解决办法
1. 在uniapp需要下载文件,但是显示情况是不能下载。所以只能使用该办法来进行下载。 2. 这有一个注意点是:如果你做的是H5的方案,那么我已经替你踩好坑了,UC浏览器是不支持blob类型的下载,以及创建a标签的方案来进行下…...

c++ 贪心算法
概念 贪心算法是一种在每一步选择中都选择当前最优解的算法策略。这种方法适用于某些特定问题,可以通过局部最优选择构建全局最优解。 特点 局部最优选择:每一步选择都选择当前看起来最优的解。无后效性:当前选择不会影响未来选择的可能性…...

15分钟学 Go 第 35 天:Go的性能调优 (7000字详细教程)
第35天:Go的性能调优 目标:理解Go语言中基本的性能优化,学习如何分析和提高Go程序的执行效率。 一、性能调优概述 性能调优是软件开发中的一个重要环节,它可以确保程序在资源有限的环境下高效运行。Go语言天生具备高效的性能表现…...

6、显卡品牌分类介绍:技嘉 - 计算机硬件品牌系列文章
技嘉科技是一家以主板、显卡在业界缔造无以撼动的地位的科技公司,其核心理念是「技术创新、质量稳定」的高标准。技嘉专注于关键技术研发,其经营范围涵盖家用、商用、电竞等多元科技领域。通过应用突破性的专利技术,技…...

Redis数据类型——针对实习面试
目录 Redis数据类型Redis常用的数据类型有哪些?String类型可以用于哪些场景?Set类型可以用于哪些场景?Bitmaps类型可以用于哪些场景?HyperLogLog类型可以用于哪些场景?Hash类型与Set类型有什么区别?Hash类型…...

roberta融合模型创新中文新闻文本标题分类
项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…...

《密码系统设计》实验二 4-6学时
文章目录 《密码系统设计》实验实验项目实验二 密码算法实现4-6 学时实践要求(30 分)1. 定义宏2. 使用特定的源文件3. 编译MIRACL库4. 配置KCM和Comba方法5. 编译和运行MEX工具6. 使用config.c工具总结1. 准备环境2. 下载和解压MIRACL库3. 定义宏4. 使用…...

Zypher Network:全栈式 Web3 游戏引擎,服务器抽象叙事的引领者
近期,《黑神话:悟空》的爆火不仅让 AAA 游戏重回焦点,也引发了玩家与开发者的热议。Web2 游戏的持续成功导致部分 Web3 玩家们的倒戈,对比之下 Web3 游戏存在生命周期短且商业模式难以明确的问题,尤其在当前加密市场环…...

2025生物发酵展(济南)为生物制造产业注入新活力共谱行业新篇章
2025第十四届国际生物发酵展将于3月3-5日济南盛大举办!产业链逐步完整,展会面积再创历史新高,展览面积较上届增涨至60000平方米,专业观众40000,品牌展商800,同期活动会议增加至50场,展会同期将举…...

git入门教程14:Git与其他工具的集成
一、Git与代码托管平台的集成 GitHub 集成方式: 在GitHub上创建或克隆仓库。在本地使用Git命令进行代码提交和推送(如git push)。GitHub提供Web界面进行代码浏览、协作和持续集成配置。 特点: 支持Pull Request,便于代…...

在Zetero中调用腾讯云API的输入密钥的问题
也是使用了Translate插件了,但是需要调用腾讯云翻译,一直没成功。 第一步就是,按照这上面方法做:百度、阿里、腾讯、有道各平台翻译API申请教程 之后就是:Zotero PDF translat翻译:申请腾讯翻译接口 主要是…...

【AD】1-8 AD24软件工程创建
1.点击文件,新建项目 2.如图进行设置工程名称和文件路径 3.创建原理图库及原理图,并保存 4.新建PCB库及PCB,并保存 5.单击右键工程保存 注意:先新建工程,在新建文件...

RT-Thread学习
文章目录 前言一、rtt的启动流程二、移植工作总结 前言 RT-Thread学习,这里记录对bsp的移植 一、rtt的启动流程 RT-Thread 支持多种平台和多种编译器,而 rtthread_startup() 函数是 RT-Thread 规定的统一启动入口。一般执行顺序是:系统先从…...

20241102在荣品PRO-RK3566开发板使用荣品预编译的buildroot通过iperf2测试AP6256的WIFI网速
20241102在荣品PRO-RK3566开发板使用荣品预编译的buildroot通过iperf2测试AP6256的WIFI网速 2024/11/2 14:18 客户端:荣耀手机HONOR 70【iPerf2 for Android】 服务器端:荣品PRO-RK3566开发板 预编译固件:update-pro-rk3566-buildroot-hdmi-2…...

网络模型——二层转发原理
网课地址:网络模型_二层转发原理(三)_哔哩哔哩_bilibili 一、路由交换 网络:用来信息通信,信息共享的平台。 网络节点(交换机,路由器,防火墙,AP)介质&#…...

【编程技巧】C++如何使用std::map管理std::function函数指针
一、问题背景 开发过程中遇到了需要根据const字符串调用不同函数的要求。在开发过程中为了快速实现功能,实际使用了if else等判断实现了不同函数的调用,徒增了不少代码行数。 明知道可以采用map管理函数指针,但是没有具体实现过,…...

导航栏小案例
实现类似于这样的效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>导航栏</title><style>*{margin: 0;padding: 0;}.div1{width: 100%;height: 60px;/* border: 1px solid blue; */background-color:rgb(…...

MyBatis一文入门精通,面试题(含答案)
一、MyBatis详细介绍 MyBatis 是一个流行的 Java 持久层框架,主要用于简化 SQL 数据库操作。它的设计初衷是通过 XML 或注解的方式配置和执行 SQL 语句,使得数据库操作更加灵活、方便和高效。相比于传统的 JDBC,MyBatis 提供了一些关键优势&…...