Netty通信框架

news2025/7/20 13:39:04

Netty框架的底层是NIO,NIO:non-blocking io 非阻塞IO

一个线程可以处理多个通道,减少线程创建数量;

读写非阻塞,节约资源:没有可读/可写数据时,不会发生阻塞导致线程资源的浪费

一、NIO三大组件

1.Channel&&Buffer

channel:

读写数据的双向通道,可以从channel将数据读入到buffer,也可以将buffer中的数据写入channel

buffer:

用来暂存数据的缓冲区

常见的channel有:
FileChannel - 文件传输的数据传输通道

DatagramChannel - UDP网络编程时的数据传输通道

SocketChannel - TCP网络编程时的数据传输通道    (客户端、服务器都能用)

ServerSocketChannel - TCP网络编程时的数据传输通道(专用于服务器)

二、Netty

Netty执行流程

Netty核心组件

1.Channel 数据通道:        

数据的载体,建立客户端和服务端通信的桥梁,连接成功后保存Channel通道。

2.EventLoop 与 EventLoopGroup:

Netty为每个Channel分配一个EventLoop,EventLoop 本身只是一个线程驱动,在其生命周期内只会绑定一个线程,让该线程处理一个 Channel 的所有 IO 事件,起到在Channel中处理数据的功能

3.ServerBootstrap 与 Bootstrap:
Bootstrap 是客户端的引导类,Bootstrap 在调用 bind()(连接UDP)和 connect()(连接TCP)方法时,会新创建一个 Channel,仅创建一个单独的、没有父 Channel 的 Channel 来实现所有的网络交换。

​ServerBootstrap 是服务端的引导类,ServerBootstarp 在调用 bind() 方法时会创建一个 ServerChannel 来接受来自客户端的连接,并且该 ServerChannel 管理了多个子 Channel 用于同客户端之间的通信。

Bootstrap来设置一些连接参数

4.ChannelHandler 与 ChannelPipeline:

ChannelHandler是消息处理器,封装在了ChannelPipeline对象中

ChannelPipeline来添加一些特定的处理器满足业务需求

5.ChannelFuture:

 Netty 中所有的 I/O 操作都是异步的,即操作不会立即得到返回结果,所以Netty定义了ChannelFuture来作为操作返回结果

    public Channel connect(String host , int port , ChannelInboundHandlerAdapter  handler, MessageToMessageEncoder encoder, ByteToMessageDecoder decoder) {
        EventLoopGroup  group = getEventLoopGroup();
        bootstrap = new Bootstrap();
        bootstrap.group(group);
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.TCP_NODELAY, true);      // 立即发送数据,设置了TCP_NODELAY选项为true,它的作用是禁用了Nagle算法。这意味着数据将被立即发送,不会等待小的数据块进行合并。
        bootstrap.option(ChannelOption.SO_KEEPALIVE, false);    // 用于控制操作系统是否发送保持活动(keep-alive)探测报文段来检测连接是否仍然活跃
        bootstrap.option(ChannelOption.ALLOW_HALF_CLOSURE, false);  // 全关闭(Full Closure):表示双方都关闭了连接,不再允许进行数据的读写操作。
                                                                          // 半关闭(Half Closure):表示一端关闭了连接,但另一端仍可以发送数据。
                                                                          // 当设置为true时,表示允许半关闭连接,即当远程端关闭连接时,本地端仍可以继续发送数据。
        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000); //连接超时毫秒数
        bootstrap.option(ChannelOption.SO_RCVBUF, 64 * 1024); //TCP数据接收缓冲区大小
        bootstrap.option(ChannelOption.SO_SNDBUF, 46 * 1024); //TCP数据发送缓冲区大小
        // bootstrap.handler(new LoggingHandler(LogLevel.DEBUG));
        channelInitializer = new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline channelPipeline = ch.pipeline();
                // channelPipeline.addLast(new LoggingHandler(LogLevel.DEBUG));
                channelPipeline.addLast("decoder", decoder);
                channelPipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
                channelPipeline.addLast("encoder", encoder);
                channelPipeline.addLast("handler", handler);
            }
        };
        bootstrap.handler(channelInitializer);
        try {
            ChannelFuture channelFuture = bootstrap.connect(host, port).syncUninterruptibly();
            if (channelFuture != null && channelFuture.isSuccess()) {
                logger.info("connect tcp server host = {}, port = {} success", host, port);
                return channelFuture.channel();
            } else {
                logger.error("connect tcp server host = {}, port = {} fail", host, port);
            }
        } catch (Exception e) {
            logger.error("connect to tcp server failed.", e);
        }
        return null;
    }

ChannelInboundHandlerAdapterMessageToMessageEncoderByteToMessageDecoder分别是Netty框架中的三个重要类,用于处理网络数据的编解码和处理。

  1. ChannelInboundHandlerAdapter是Netty中用于处理入站数据的抽象类。它提供了一系列的回调方法,可根据实际需求进行重写,用于处理不同的入站事件和操作。通常情况下,我们的自定义处理器需要继承该类,并且实现自定义的业务逻辑。

  2. MessageToMessageEncoder是一个编码器,用于将一种消息类型转换为另一种消息类型。它将一个出站消息对象转换为另一个出站消息对象,例如将一个POJO对象编码为字节数据。通过继承该抽象类并重写encode()方法,我们可以实现自定义的消息编码逻辑,以满足特定的协议或需求。

  3. ByteToMessageDecoder是一个解码器,用于将字节数据解码为其他形式的数据,如将字节数据解码为POJO对象或其他自定义消息对象。它将一个入站的字节缓冲区转换为出站消息对象。通过继承该抽象类并重写decode()方法,我们可以根据实际需求实现自定义的消息解码逻辑,以满足特定的协议或需求。

这三个类在Netty中的应用通常是组合使用的,用于构建完整的网络数据处理链。具体来说,ChannelInboundHandlerAdapter用于处理入站数据的不同事件和操作,MessageToMessageEncoder用于将出站消息对象编码为其他形式的消息对象,而ByteToMessageDecoder用于将入站的字节数据解码为其他形式的消息对象。通过灵活组合和重写这些类的方法,我们可以实现定制的网络数据处理逻辑。

其中ChannelInitializer 是一个用于初始化 SocketChannel 的抽象类。它的 initChannel() 方法会在每个新连接被接受时调用,用于配置该连接的 ChannelPipeline。

在 initChannel() 方法中,我们可以通过 channelPipeline 对象来设置和添加各种处理器(handlers)到 ChannelPipeline 中,以定义数据的处理流程。

在这段代码中,通过 channelPipeline 对象按照一定的顺序添加了以下处理器:

  1. decoder:这是一个 ByteToMessageDecoder,用于将入站的字节数据解码为其他形式的消息对象。
  2. StringDecoder:这是一个 Netty 提供的内置解码器,用于将入站的字节数据解码为字符串形式的消息对象。指定编码格式为 UTF-8
  3. encoder:这是一个 MessageToMessageEncoder,用于将出站消息对象编码为其他形式的消息对象。
  4. handler:这是一个自定义的 ChannelInboundHandlerAdapter,用于处理入站数据的不同事件和操作。

通过这样的方式,我们可以构建一个完整的数据处理流程,根据实际需求来解码、编码和处理网络消息。在 ChannelInitializer 的 initChannel() 方法中,我们可以按照需求自由添加或修改处理器,以满足特定的业务需求。

ChannelFuture channelFuture = bootstrap.connect(host, port).syncUninterruptibly();

这段代码是使用 bootstrap 对象创建一个客户端连接,并返回一个 ChannelFuture 对象。

以下是代码的执行步骤:

  1. bootstrap.connect(host, port):使用指定的主机和端口号,创建一个连接到目标服务器的操作,并返回一个 ChannelFuture 对象。
  2. .syncUninterruptibly():阻塞当前线程,等待连接操作完成。syncUninterruptibly() 方法会阻塞当前线程,直到连接操作完成或发生异常,而不会响应中断。
  3. channelFuture:连接操作完成后,返回一个 ChannelFuture 对象,可以通过该对象获取操作的结果。

通过这段代码,可以同步地创建一个客户端连接,并在连接操作完成后获取连接的 ChannelFuture 对象,以便后续的操作和处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1157339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年11月4日(星期六)骑行香杆箐

2023年11月4日 (星期六) 骑行香杆箐&#xff0c;早8:30到9:00&#xff0c; 郊野公园西门&#xff0c;9:30准时出发 【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点:大观公园门口集合 &#xff0c;家住东&#xff0c;南&#xff0c;北的骑友在下列…

高性能消息中间件 - Kafka3.x(四)

文章目录 高性能消息中间件 - Kafka3.x&#xff08;四&#xff09;Kafka监控-Kafka eagle&#xff08;EFAK 2.1.0版本&#xff09;⭐修改每个kafka的配置信息启动MySQL在mysql中创建名为ke的数据库开始安装并启动kafka-eagle Kafka的Kraft模式&#xff08;新版Kafka特性&#x…

【Redis】redis的过期策略如何实现有关定时器的补充

文章目录 redis的过期策略如何实现关于定时器的补充基于优先级队列/堆实现的定时器基于时间轮实现的定时器 redis的过期策略如何实现 注意&#xff1a;不能直接遍历所有的key来判断当前key是否过期&#xff0c;这样子效率非常低&#xff0c;redis整体策略是&#xff1a;定期删…

系列十五、idea全局配置

一、全局Maven配置 IDEA启动页面>Customize>All settings>Build,Execution,Deployment>Build Tools>Maven 二、全局编码配置 IDEA启动页面>Customize>All settings>Editor>File Encodings 三、全局激活DevTools配置 IDEA启动页面>Customize>A…

企业通过ISO/IEC 27001的必要性阐述

文章目录 什么是ISO 27001?ISO 27001认证的必要性1&#xff0c;保护信息资产2&#xff0c;合规性要求3&#xff0c;提高客户信任4&#xff0c;降低安全风险5&#xff0c;提高内部效率6&#xff0c;改进供应链安全7&#xff0c;提高员工意识8&#xff0c;连续改进 推荐阅读 什么…

二叉树问题——前中后遍历数组构建二叉树

摘要 利用二叉树的前序&#xff0c;中序&#xff0c;后序&#xff0c;有序数组来构建相关二叉树的问题。 一、构建二叉树题目 105. 从前序与中序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树 889. 根据前序和后序遍历构造二叉树 617. 合并二叉树 226. 翻转二…

Hadoop相关知识点

文章目录 一、主要命令二、配置虚拟机2.1 设置静态ip2.2 修改主机名及映射2.3 修改映射2.4 单机模式2.5 伪分布式2.6 完全分布式 三、初识Hadoop四、三种模式的区别4.1、单机模式与伪分布式模式的区别4.2、特点4.3、配置文件的差异4.3.1、单机模式4.3.2、伪分布式模式4.3.3、完…

JVM虚拟机:堆结构的逻辑分区

堆内存的逻辑分区 堆内存的逻辑分区如下所示: 堆内存中分为新生代和老年代,二者空间大小1:3。在新生代里面分为两类区域(eden、survivor),三个区域(eden、survivor、survivor),三个区大小比例为8:1:1。 对象存放的位置 栈 当我们new一个对象的时候,首先会将对象…

Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】

一、网关简介 大家都都知道在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去用。 这样的架构&#xff0c;会存在着诸多…

我在Vscode学OpenCV 处理图像

既然我们是面向Python的OpenCV&#xff08;OpenCV for Python&#xff09;那我们就必须要熟悉Numpy这个库&#xff0c;尤其是其中的数组的库&#xff0c;Python是没有数组的&#xff0c;唯有借助他库才有所实现想要的目的。 # 老三样库--事先导入 import numpy as np import c…

高性能消息中间件 - Kafka3.x(二)

文章目录 高性能消息中间件 - Kafka3.x&#xff08;二&#xff09;Kafka生产者⭐生产者发生原理⭐RecordAccumulator源码简单分析⭐Java Api生产者的重要参数⭐环境准备创建一个名为java-api-test的topic主题⭐命令行开启一个consumer消费者监听名为java-api-test的topic⭐pom.…

5、QtCharts 曲线美化

文章目录 效果ui 设置dialog.hdialog.cpp 效果 ui 设置 dialog.h #ifndef DIALOG_H #define DIALOG_H#include <QDialog> #include <QtCharts> #include <QLineSeries> #include <QGraphicsScene> #include <QTimer> #include <QSplineSerie…

陕西某小型水库雨水情测报及大坝安全监测项目案例

项目背景 根据《陕西省小型病险水库除险加固项目管理办法》、《陕西省小型水库雨水情测报和大坝安全监测设施建设与运行管理办法》的要求&#xff0c;为保障水库安全运行&#xff0c;对全省小型病险水库除险加固&#xff0c;建设完善雨水情测报、监测预警、防汛道路、通讯设备、…

如何有效使用蜂邮EDM和vba批量发送邮件?

蜂邮EDM和vba批量发送邮件的方法&#xff1f;怎么使用蜂邮EDM和vba代码群发电子邮件&#xff1f; 批量发送邮件已经成为一种不可或缺的沟通方式。蜂邮EDM和VBA是两个功能强大的工具&#xff0c;可以帮助您在邮件营销和业务通信中实现高效的批量发送邮件操作。接下来将介绍如何…

关于Goby反制上线CS中的各种问题

前言 ​ Goby作为新一代网络安全技术&#xff0c;通过为目标建立完整的资产数据库&#xff0c;实现快速的安全应急&#xff0c;日常为广大师傅提供了便捷的渗透体验。最近有观察到有关于某些蜜罐出现了Goby反制的指纹&#xff0c;顿时就起了兴趣进行研究Goby的反制&#xff0c…

AIGC究竟是什么?为什么今年大家都在讨论?

目录 一、什么是AIGC 二、AIGC发展阶段 三、AIGC的技术应用 AIGC的应用场景 四、AIGC的伦理、风险与未来 五、说在最后 在23年初&#xff0c;大家的视野范围内突然出现了一种叫ChatGPT的产品&#xff0c;这是由OpenAI研发的一种基于深度学习和自然语言处理技术的文本生成…

SpringBoot_mybatis-plus使用json字段

mybatis-plus使用json字段 1.前言2.方案分析2.1 为什么是json2.2 数据库的选择 3. 实战3.1 使用text字段(h2数据库)3.1.1 建表语句3.1.2 数据操作与查询 3.2 使用json字段(mysql数据库)3.2.1 建表语句3.2.2 数据操作与查询 4. 附录4.1 MySQL JSON索引用法 5. 参考文档 1.前言 …

无需服务器内网穿透Windows下快速搭建个人WEB项目

&#x1f4d1;前言 本文主要是windows下内网穿透文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力…

今日温馨早安问候语,祝大家平安健康早安吉祥

用清晨的阳光沐浴&#xff0c;给你舒展;用清新的空气洗漱&#xff0c;给你舒心;伴清莹的雨露散步&#xff0c;给你舒情;向美好的一天欢呼&#xff0c;给你舒怀&#xff0c;用快乐的词汇凝聚&#xff0c;给你祝福&#xff0c;祝你在绚丽的晨光中走好每一天。朋友&#xff0c;早安…

算法升级之路(六)

给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1]] 解题思路&…