Netty和传统NIO之间的比较

  1. Netty回显服务器实现:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class NettyEchoServer {public static void main(String[] args) throws InterruptedException {NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);NioEventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ch.pipeline().addLast(new EchoServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);serverBootstrap.bind(8080).sync().channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}private static class EchoServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) {System.out.println("Received message: " + msg);ctx.writeAndFlush(msg);}}
}

上述代码是一个使用Netty实现的回显服务器。让我们逐行解释代码的实现:

  • 首先,我们创建了两个NioEventLoopGroup,一个用于接收客户端连接(bossGroup),另一个用于处理客户端连接上的请求(workerGroup)。
  • 然后,我们创建一个ServerBootstrap实例,并配置各种参数,如所使用的通道类型、事件处理器等。
  • childHandler()方法中,我们初始化处理器链,这里只有一个EchoServerHandler处理器。
  • EchoServerHandler是一个继承自SimpleChannelInboundHandler的处理器,它处理接收到的消息并将其回显给客户端。
  • 接下来,我们绑定服务器端口并启动服务器。
  • 最后,我们关闭并释放资源。
  1. 传统NIO回显服务器实现:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;public class TraditionalNioEchoServer {public static void main(String[] args) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);Selector selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectedKeys.iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();if (key.isAcceptable()) {ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();SocketChannel socketChannel = serverChannel.accept();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = socketChannel.read(buffer);if (bytesRead == -1) {socketChannel.close();continue;}buffer.flip();String message = new String(buffer.array(), 0, bytesRead);System.out.println("Received message: " + message);socketChannel.write(buffer);key.interestOps(SelectionKey.OP_READ);}}}}
}

上述代码是一个使用传统NIO实现的回显服务器。让我们逐行解释代码的实现:

  • 首先,我们创建一个ServerSocketChannel实例,并将其绑定到指定的端口上。
  • 然后,我们配置ServerSocketChannel为非阻塞模式,并创建一个Selector实例。
  • Selector上注册ServerSocketChannel,并将其设置为接受连接的操作。
  • 进入主循环,调用selector.select()等待就绪的事件。
  • 一旦有事件就绪,我们获取就绪的SelectionKey集合,并遍历处理每个就绪的SelectionKey
  • 如果SelectionKey是可接受的,我们接受客户端连接,并将客户端SocketChannel注册到Selector上,并设置为可读操作。
  • 如果SelectionKey是可读的,我们读取客户端发送的数据,并将其回显给客户端。
  • 最后,我们继续循环处理就绪的事件。

- 其他特性

当涉及到Netty的高级抽象和扩展性时,它们如何帮助开发网络应用程序主要体现在以下几个方面:

  1. 高级抽象:Netty提供了一组高级抽象,如ChannelHandlerChannelPipelineByteBuf等,它们封装了底层的网络操作和数据处理,简化了开发过程。这些高级抽象使开发人员能够专注于业务逻辑而不必过多关注网络操作的细节。例如,通过使用ChannelHandlerChannelPipeline,开发人员可以轻松地定义事件处理器链,处理不同类型的事件,以及对数据进行编解码等操作。这种高级抽象使得编写网络应用程序变得更加简洁和可读。

下面是一个使用Netty高级抽象的简单示例,它演示了一个回显服务器:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class NettyEchoServer {public static void main(String[] args) throws InterruptedException {NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);NioEventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ch.pipeline().addLast(new EchoServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);serverBootstrap.bind(8080).sync().channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}private static class EchoServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) {System.out.println("Received message: " + msg);ctx.writeAndFlush(msg);}}
}

在上述代码中,我们使用了Netty的高级抽象和组件:

  • ServerBootstrap:它是Netty启动服务器的入口,它封装了服务器的配置和启动过程。
  • ChannelInitializer:它是用于初始化新的连接的Channel的处理器。我们可以在其中添加我们自定义的处理器。
  • ChannelOption:它是用于配置ServerBootstrap的选项,例如设置TCP的参数。
  • SimpleChannelInboundHandler:它是一个抽象类,提供了一些方便的方法来处理不同类型的事件,比如channelRead0()方法用于处理接收到的消息。

通过使用这些高级抽象,我们可以轻松地定义和配置服务器,并实现业务逻辑的处理。

  1. 扩展性:Netty具有良好的可扩展性,允许开发人员自定义和添加自己的处理器和组件。Netty的设计使得添加新的功能或修改现有功能变得相对简单。

以下是一个示例,展示了如何自定义一个处理器来处理特定的业务需求:

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;public class CustomHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) {// 自定义业务逻辑处理// ...}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// 异常处理// ...}
}

在上述代码中,我们创建了一个自定义处理器CustomHandler,继承自SimpleChannelInboundHandler。通过重写channelRead0()方法,我们可以自定义处理接收到的消息的逻辑。通过使用Netty的高级抽象和扩展性,开发人员可以更轻松地构建和扩展网络应用程序。高级抽象简化了网络操作和数据处理的编程模型,使开发人员能够专注于业务逻辑而不必处理底层细节。同时,Netty的扩展性允许开发人员根据自己的需求添加自定义的处理器和组件,以实现特定的功能和逻辑。这种灵活性使得Netty成为一个强大且受欢迎的框架,用于构建高性能的网络应用程序。


还有一些方面需要考虑:

  1. 异步和事件驱动:Netty是基于事件驱动和异步的I/O模型。它使用了NIO(Non-blocking I/O)机制,使得应用程序能够处理大量的并发连接而不会阻塞。Netty将I/O操作转化为事件,并通过回调机制通知应用程序处理这些事件。这种异步和事件驱动的特性使得Netty非常适合构建高性能、可扩展的网络应用程序,能够处理大量的并发连接和高负载。

  2. 高性能和可伸缩性:Netty通过优化底层网络操作和数据处理,提供了高性能和可伸缩性。它使用了一些技术,如零拷贝(zero-copy)和内存池(memory pooling),以减少数据复制和内存分配的开销。Netty还使用了多线程和线程池来处理并发连接和请求,并通过事件循环(Event Loop)机制来实现高效的事件处理。这些优化措施使得Netty能够处理大规模的并发连接,并具有出色的性能表现。

  3. 多协议支持:Netty支持多种常见的网络协议,如TCP、UDP、HTTP、WebSocket等。它提供了一组相应的高级抽象和组件,使得开发人员能够轻松地构建基于这些协议的应用程序。Netty的高级抽象和扩展性使得开发人员能够自定义和扩展协议的处理逻辑,以满足特定的需求。

总之,Netty的高级抽象和扩展性使得开发人员能够以简洁、灵活和高效的方式构建网络应用程序。它提供了丰富的工具和组件,简化了网络编程的复杂性,同时提供了优异的性能和可伸缩性。无论是构建高性能服务器、实时通信应用还是分布式系统,Netty都是一个强大而可靠的选择。

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

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

相关文章

十个Java字符串操作示例程序

1. 如何在String中获取不同的字符及其计数&#xff1f; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors;public class DistinctCharsCount {public static void main(String[] args) {printDistinctCharsWithCo…

定时器开发基础

1定时器的基本概述 通过滴漏和漏沙瓶这两个例子简单讲述定时器的基本工作原理。 STM32的常见的定时器资源&#xff1a; 系统嘀嗒定时器SysTick、看门狗定时器WatchDog、实时时钟RTC、基本定时器、通用定时器、高级定时器。 系统嘀嗒定时器SysTick &#xff1a;这是一个集成在C…

中移(苏州)软件技术有限公司面试问题与解答(2)—— Linux内核内存初始化的完整流程1

接前一篇文章&#xff1a;中移&#xff08;苏州&#xff09;软件技术有限公司面试问题与解答&#xff08;1&#xff09;—— 可信计算国密标准 本文参考以下文章&#xff1a; 启动期间的内存管理之初始化过程概述----Linux内存管理(九) Linux初始化 特此致谢&#xff01; 本…

JavaScript 自定义分页组件

仿boostrap 前端分页组件的实现 一 写一个前端自定义分页组件&#xff0c;需要考虑以下问题 需要一个<ul id"pagination"></ul>标签 total; // 总数据的数量 pageSize; // 一页显示数量 pageIndex; // 当前页 二 实现细节 编写html文件 index.html…

Debezium日常分享系列之:Debezium and TimescaleDB

Debezium日常分享系列之&#xff1a;Debezium and TimescaleDB 一、TimescaleDB二、完整案例三、Hypertables四、Continuous aggregates五、Compression六、结论 一、TimescaleDB TimescaleDB 是一个开源数据库&#xff0c;旨在使 SQL 对于时间序列数据具有可扩展性。它是作为…

代码随想录算法训练营第二十四天| 77. 组合

77. 组合 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 解题思路&#xff1a;纵向遍历&#xff0c;遇到叶子节点返回上一节点 java&#xff1a; class Solution {List<List<Integer>> result new ArrayList&l…

ACL配置

ACL&#xff1a;访问控制列表 在路由器流量进或出接口上&#xff0c;匹配流量产生动作-- 允许 拒绝 &#xff08;访问限制&#xff09;定义感兴趣流量--- 匹配流量后&#xff0c;将流量提交给其他的协议进行策略 匹配规则&#xff1a; 至上而下逐一匹配&#xff0c;上条匹配…

蓝桥杯(C++ 整数删除 优先队列 )

优先队列&#xff1a; 优先队列具有队列的所有特性&#xff0c;包括队列的基本操作&#xff0c;只是在这基础上添加了内部的一个排序&#xff0c;它本质是一个堆实现的。 1.头文件&定义 #include <queue> #include <functional> //greater<>// 定义 p…

1d 卷积网络笔记

目录 这个是1d 卷积网络合集&#xff1a; resnet1d的 这个是1d 卷积网络合集&#xff1a; https://github.com/StChenHaoGitHub/1D-deeplearning-model-pytorch/blob/main/ResNet50.py resnet1d的 https://github.com/hsd1503/resnet1d

2023 年顶级前端工具

谁不喜欢一个好的前端工具&#xff1f;在本综述中&#xff0c;您将找到去年流行的有用的前端工具&#xff0c;它们将帮助您加快开发工作流程。让我们深入了解一下&#xff01; 在过去的 12 个月里&#xff0c;我在我的时事通讯 Web Tools Weekly 中分享了数百种工具。我为前端…

经典数据库练习题及答案

数据表介绍 --1.学生表 Student(SId,Sname,Sage,Ssex) --SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Course(CId,Cname,TId) --CId 课程编号,Cname 课程名称,TId 教师编号 --3.教师表 Teacher(TId,Tname) --TId 教师编号,Tname 教师姓名 --4.成绩…

JavaScript DOM可以做什么?

1、通过id获取标签元素 DOM是文档对象模型&#xff0c;它提供了一些属性和方法来方便我们操作document对象&#xff0c;比如getElementById()方法可以通过某个标签元素的id来获取这个标签元素 // 用法 window.document.getElementById(id); // 例子 <!DOCTYPE html> &l…

深度学习模型之yolov8实例分割模型TesorRT部署-python版本

1 模型转换 从github上下载官方yolov8版本&#xff0c;当前使用的版本是2023年9月份更新的版本&#xff0c;作者一直在更新。官网地址 2 加载模型 模型的训练和测试在官方文档上&#xff0c;有详细的说明&#xff0c;yolov8中文文档这里不做过多说明&#xff0c;v8现在训练是…

C#设计模式教程(5):建造者模式

建造者模式的定义 建造者模式(Builder Pattern)是一种创建型设计模式,它允许你创建复杂对象的步骤分离,这样你可以使用相同的创建过程生成不同的表示。建造者模式通常用于处理那些包含多个成员变量的类,特别是当这些成员变量需要经过复杂步骤构建或者有大量可选参数时。 …

一个查看各个软件版本生命周期的网站

在做开发或学习时&#xff0c;经常翻文档找各个SDK版本的支持信息&#xff0c;比较麻烦。发现一个罗列 JDK、SpringBoot、PHP等常见的应用的生命周期追踪网站&#xff1a;https://endoflife.date/。 endoflife.date 目前追踪 286 个产品。

智能驾驶新浪潮:SSD与UFS存储技术如何破浪前行?-UFS篇

如果说SSD是赛道上的超级跑车&#xff0c;那UFS更像是专为智能汽车定制的高性能轻量化赛车。UFS采用串行接口技术&#xff0c;像是闪电侠一样&#xff0c;将数据传输的速度推向新高&#xff0c;大幅缩短了系统启动时间和应用程序加载时间&#xff0c;这对追求即时反应的ADAS系统…

从零开始的 dbt 入门教程 (dbt core 命令进阶篇)

引 根据第一篇文章的约定&#xff0c;我想通过接下来的几篇文章带大家进一步了解 dbt 的用法&#xff0c;原计划这篇文章我会介绍 dbt 命令的进阶用法&#xff0c;进一步认识 dbt 的配置以及如何创建增量表等等零零散散十几个方面的知识点&#xff0c;结果在我写完命令部分发现…

深度学习中Numpy的一些注意点(多维数组;数据类型转换、数组扁平化、np.where()、np.argmax()、图像拼接、生成同shape的图片)

文章目录 1多维数组压缩维度扩充维度 2numpy类型转换深度学习常见的float32类型。 3数组扁平化4np.where()的用法5np.argmax()6图像拼接7生成同shape的图片&#xff0c;指定数据类型 1多维数组 a.shape(3,2);既数组h3&#xff0c;w2 a.shape(2,3,2);这里第一个2表示axis0维度上…

Unity文字游戏开发日志(2)——存档与读档

存档与读档较为简单的实现 今天学习了如何存读档。 采用了Unity自带的方式PlayerPrefs 写了一个示例代码 功能是&#xff1a;建立一个名字的新档&#xff0c;每次打开游戏名字都会变。 PlayerPrefs.SetString("save","kkk");//创建名为save数据&#…