Netty-Netty基础应用与了解

news2025/1/10 16:37:49

前言

Netty 的优势

        1、 API 使用简单,开发门槛低;
        2、功能强大,预置了多种编解码功能,支持多种主流协议;
        3、定制能力强,可以通过 ChannelHandler 对通信框架进行灵活地扩展;
        4、性能高,通过与其他业界主流的 NIO 框架对比, Netty 的综合性能最优;
        5、成熟、稳定, Netty 修复了已经发现的所有 JDK NIO BUG ,业务开发人员不需要再为 NIO 的 BUG 而烦恼;
        6、社区活跃,版本迭代周期短,发现的 BUG 可以被及时修复,同时,更多的新功能会加入;
        7、经历了大规模的商业应用考验,质量得到验证。

为什么不用 Netty5

       Netty5 已经停止开发了。

为什么 Netty 使用 NIO 而不是 AIO

        Netty 不看重 Windows 上的使用,在 Linux 系统上, AIO 的底层实现仍使用 EPOLL ,没有
很好实现 AIO ,因此在性能上没有明显的优势,而且被 JDK 封装了一层不容易深度优化。
AIO 还有个缺点是接收数据需要预先分配缓存 , 而不是 NIO 那种需要接收时才需要分配
缓存 , 所以对连接数量非常大但流量小的情况 , 内存浪费很多。
        而且 Linux AIO 不够成熟,处理回调结果速度跟不上处理需求。
作者原话:
Not faster than NIO (epoll) on unix systems (which is true)
There is no daragram suppport Unnecessary threading model (too much abstraction without usage)

为什么不用 Mina

        简单来说,Mina 几乎不再更新了, Netty 本来就是因为 Mina 不够好所以开发出来的。

第一个 Netty 程序

BootstrapEventLoop(Group) Channel

        Bootstrap 是 Netty 框架的启动类和主入口类,分为客户端类 Bootstrap 和服务器类
ServerBootstrap 两种。
        Channel 是 Java NIO 的一个基本构造。
        它代表一个到实体(如一个硬件设备、一个文件、一个网络套接字或者一个能够执行一
个或者多个不同的 I/O 操作的程序组件)的开放连接,如读操作和写操作。
        目前,可以把 Channel 看作是传入(入站)或者传出(出站)数据的载体。因此,它
可以被打开或者被关闭,连接或者断开连接。
        EventLoop 暂时可以看成一个线程、 EventLoopGroup 自然就可以看成线程组。

事件和 ChannelHandlerChannelPipeline

         Netty 使用不同的事件来通知我们状态的改变或者是操作的状态。这使得我们能够基于
已经发生的事件来触发适当的动作。
        Netty 事件是按照它们与 入站 出站 数据流的相关性进行分类的。
        可能由入站数据或者相关的状态更改而触发的事件包括: 连接已被激活或者连接失活;
数据读取;用户事件;错误事件。
        出站事件是未来将会触发的某个动作的操作结果,这些动作包括: 打开或者关闭到远程
节点的连接;将数据写到或者冲刷到套接字。
         每个事件都可以被分发给 ChannelHandler 类中的某个用户实现的方法,既然事件分为
入站和出站,用来处理事件的 ChannelHandler 也被分为可以处理入站事件的 Handler 和出站
事件的 Handler,当然有些 Handler 既可以处理入站也可以处理出站。
         Netty 提供了大量预定义的可以开箱即用的 ChannelHandler 实现,包括用于各种协议
(如 HTTP 和 SSL/TLS)的 ChannelHandler。
        基于 Netty 的网络应用程序中根据业务需求会使用 Netty 已经提供的 ChannelHandler 或
者自行开发 ChannelHandler,这些 ChannelHandler 都放在 ChannelPipeline 中统一管理,事件
就会在 ChannelPipeline 中流动,并被其中一个或者多个 ChannelHandler 处理。

 

ChannelFuture

         Netty 中所有的 I/O 操作都是异步的,我们知道“异步的意思就是不需要主动等待结果
的返回,而是通过其他手段比如,状态通知,回调函数等”,那就是说至少我们需要一种获
得异步执行结果的手段。
         JDK 预置了 interface java.util.concurrent.Future,Future 提供了一种在操作完成时通知
应用程序的方式。 这个对象可以看作是一个异步操作的结果的占位符; 它将在未来的某个时
刻完成,并提供对其结果的访问。 但是其所提供的实现,只允许手动检查对应的操作是否已
经完成,或者一直阻塞直到它完成。这是非常繁琐的,所以 Netty 提供了它自己的实现
ChannelFuture ,用于在执行异步操作的时候使用。
        一般来说,每个 Netty 的出站 I/O 操作都将返回一个 ChannelFuture

​​​Demo

服务端:


public class EchoServer  {
    private static final Logger LOG = LoggerFactory.getLogger(EchoServer.class);

    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws InterruptedException {
        int port = 9999;
        EchoServer echoServer = new EchoServer(port);
        LOG.info("服务器即将启动");
        echoServer.start();
        LOG.info("服务器关闭");
    }

    public void start() throws InterruptedException {
        /*线程组*/
        EventLoopGroup group  = new NioEventLoopGroup();
        try {
            /*服务端启动必备*/
            ServerBootstrap b = new ServerBootstrap();
            b.group(group)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    });

            /*异步绑定到服务器,sync()会阻塞到完成*/
            ChannelFuture f = b.bind().sync();
            LOG.info("服务器启动完成。");
            /*阻塞当前线程,直到服务器的ServerChannel被关闭*/
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }


}
服务端处理:

public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf)msg;
        System.out.println("server accept :" + in.toString(CharsetUtil.UTF_8));
        ctx.writeAndFlush(in);

        //ctx.close();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("连接已建立");
        super.channelActive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

客户端:


public class EchoClient {

    private final int port;
    private final String host;

    public EchoClient(int port, String host) {
        this.port = port;
        this.host = host;
    }

    public void start() throws InterruptedException {

        /*线程组*/
        EventLoopGroup group  = new NioEventLoopGroup();
        try {
            /*客户端启动必备,和服务器的不同点*/
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)/*指定使用NIO的通信模式*/
                    /*指定服务器的IP地址和端口,和服务器的不同点*/
                    .remoteAddress(new InetSocketAddress(host,port))
                    /*和服务器的不同点*/
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler());

                        }
                    });
            /*异步连接到服务器,sync()会阻塞到完成,和服务器的不同点*/
            ChannelFuture f = b.connect().sync();
            f.channel().closeFuture().sync();/*阻塞当前线程,直到客户端的Channel被关闭*/
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new EchoClient(9999,"127.0.0.1").start();
    }
}

客户端处理:


public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    /*读取到网络数据后进行业务处理,并关闭连接*/
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        System.out.println("client Accept"+msg.toString(CharsetUtil.UTF_8));
        //关闭连接
        ///ctx.close();
    }

    /*channel活跃后,做业务处理*/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.copiedBuffer(
                "Hello,Netty",CharsetUtil.UTF_8));
//        ctx.pipeline().write()
//        ctx.channel().write()
        ctx.alloc().buffer();
    }
}

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

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

相关文章

BGP协议概念与配置(HCIP完整版)

目录 一、BGP协议基础 1、路由的分类 2、为什么要使用BGP协议 3、BGP概述 4、AS号 二、BGP协议概述 1、场景 2、作用 3、优势 4、BGP邻居类型 5、BGP特征 6、BGP报文类型 7、BGP工作过程 8、BGP状态 9、BGP路由默认优先级为255 10、BGP邻居关系建立的完整流程 …

【深度学习:视觉基础模型】视觉基础模型 (VFM) 解释

【深度学习&#xff1a;视觉基础模型】视觉基础模型 VFM 解释 了解视觉基础模型从 CNN 到 Transformer 的演变自我监督和适应能力 流行的视觉基础模型DINO&#xff08;自蒸馏&#xff0c;无标签&#xff09;SAM&#xff08;分段任意模型&#xff09;SegGPTMicrosofts Visual Ch…

【uview2.0】Keyboard 键盘 与 CodeInput 验证码输入 结合使用 uview

https://www.uviewui.com/components/codeInput.html &#xff08;CodeInput 验证码输入&#xff09; https://www.uviewui.com/components/keyboard.html &#xff08;Keyboard 键盘&#xff09; <u-keyboard mode"number" :dotDisabled"true" :show&q…

分割、合并、转换、重组:强大的自部署 PDF 处理工具 | 开源日报 No.143

Stirling-Tools/Stirling-PDF Stars: 13.2k License: GPL-3.0 这个项目是 Stirling-PDF&#xff0c;它是一个功能强大的基于本地主机的 Web PDF 操作工具&#xff0c;使用 Docker 进行部署。其主要功能包括分割、合并、转换、重新组织 PDF 文件以及添加图片、旋转和压缩等多种…

供应链+低代码,实现数字化【共赢链】转型新策略

在深入探讨之前&#xff0c;让我们首先明确供应链的基本定义。供应链可以被理解为一个由采购、生产、物流配送等环节组成的网状系统&#xff0c;它始于原材料的采购&#xff0c;经过生产加工&#xff0c;最终通过分销和零售环节到达消费者手中。 而数字化供应链&#xff0c;则是…

STM32F103RCT6使用数据手册及应用示例程序分享

STM32F103RCT6是意法半导体&#xff08;STMicroelectronics&#xff09;推出的一款Cortex-M3内核的高性能微控制器。它具有丰富的外设功能和强大的处理能力&#xff0c;适用于多种应用场景。 要进行手册数据分析&#xff0c;首先需要下载并查阅STM32F103RCT6的技术参考手册。可…

三菱plc学习入门(三,FB模块)

小编很抱歉&#xff0c;因为小编是以基恩士&#xff0c;三菱的plc一起学习并找发现不同&#xff01;&#xff01;&#xff01;并结合工作的案例来进行学习&#xff0c;所以内容上与系统的学习还是存在差异。如果只是单独的学习此篇文章&#xff0c;如果对您有帮助&#xff0c;欢…

回归预测 | Matlab基于SO-BiLSTM蛇群算法优化双向长短期记忆神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于SO-BiLSTM蛇群算法优…

深入了解鸿鹄电子招投标系统:Java版企业电子招标采购系统的核心功能

随着市场竞争的加剧和企业规模的扩大&#xff0c;招采管理逐渐成为企业核心竞争力的重要组成部分。为了提高招采工作的效率和质量&#xff0c;我们提出了一种基于电子化平台的解决方案。该方案旨在通过电子化招投标&#xff0c;使得招标采购的质量更高、速度更快&#xff0c;同…

Kubernetes/k8s的存储卷/数据卷

k8s的存储卷/数据卷 容器内的目录和宿主机的目录挂载 容器在系统上的生命周期是短暂的&#xff0c;delete&#xff0c;k8s用控制创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会回复到初始状态 一旦回到初始状态&#xff0c;所有的后天编辑的文件都会消失…

pytorch10:正则化(weight_decay、dropout、Batch Normalization)

目录 一、正则化regularization1.概念2.过拟合3.减小方差策略4 正则化--权值衰减 二、正则化-dropout2.1 dropout概念2.2 数据尺度变化2.3 nn.Dropout2.4 两种模式 三、Batch Normalization3.1 ICS现象&#xff08;Internal Covariate Shift&#xff0c;内部协变量偏移)3.2 BN原…

Web实战丨基于django+html+css+js的学院门户网站

文章目录 写在前面项目概述基本信息项目需求 项目框架程序设计运行结果项目总结 写在后面 写在前面 本期内容&#xff1a;基于DjangoHtmlCssJavaScript的学院门户网站 项目需求&#xff1a; pythondjango 项目下载地址&#xff1a;https://download.csdn.net/download/m0_6…

SemiDrive E3 打包说明

一、 概述 本文介绍 E3 PAC 打包&#xff0c;编译器生成 bin 文件需要通过打包生成 PAC 包&#xff0c;再通过 SDToolBox 工具将 PAC 包烧写到芯片&#xff0c;PAC 包的物理载体分为 Flash、eMMC、SD&#xff0c;一个 PAC包最多支持 3 个BootPackage&#xff1b;本文主要描述打…

深入理解C#中的引用类型、引用赋值以及 `ref` 关键字

深入理解C#中的引用类型、引用赋值以及 ref 关键字 在C#编程中&#xff0c;理解引用类型、引用赋值以及 ref 关键字的使用对于编写高效、可靠的代码至关重要。本文将深入探讨这些概念&#xff0c;帮助您更好地理解C#的工作原理。 引用类型简介 在C#中&#xff0c;所有的类型都…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-4系统的可控性Controllability(LTI)线性时不变

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-4系统的可控性Controllability-LTI线性时不变

K8S的存储卷---数据卷

容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的。delete&#xff0c;K8S用控制器创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会恢复到初始状态。一旦回到初始状态&#xff0c;所有的后天编辑的文件都会消失 容器和节点之间创建一个…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷⑧

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷8 目录 需要竞赛软件包环境以及备赛资源可私信博主&#xff01;&#xff01;&#xff01; 2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷8 模块一 …

基于传统机器学习模型算法的项目开发详细步骤

1 场景分析 1.1 项目背景 描述开发项目模型的一系列情境和因素&#xff0c;包括问题、需求、机会、市场环境、竞争情况等 1.2. 解决问题 传统机器学习在解决实际问题中主要分为两类&#xff1a; 有监督学习&#xff1a;已知输入、输出之间的关系而进行的学习&#xff0c;从而…

e2studio开发LPS28DFW气压计(1)----轮询获取气压计数据

e2studio开发LPS28DFW气压计.1--轮询获取气压计数据 概述视频教学样品申请完整代码下载产品特性通信模式速率新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user…

从0开始学Git指令(2)

从0开始学Git指令 因为网上的git文章优劣难评&#xff0c;大部分没有实操展示&#xff0c;所以打算自己从头整理一份完整的git实战教程&#xff0c;希望对大家能够起到帮助&#xff01; 工作区&#xff08;Working Directory&#xff09; 就是你在电脑里能看到的目录&#x…