当前位置: 首页 > news >正文

Netty学习

是什么

想象一下你要在两个城市之间建立一条高效的物流系统:

  • 传统方式(BIO):每来一件货物(一个请求),我就派一辆卡车和一个司机专门负责这趟运输。司机要一直等到货物装完、运输、卸完才能回来接下一单。如果货物没到,司机就得空等,非常浪费资源。
  • Netty 方式(NIO):我建立一个智能物流中心(Netty)。这个中心有一个总调度员(Reactor 线程),他负责盯着所有货车的状态(连接通道是否就绪)。一旦某辆货车的货物准备好了(数据就绪),调度员就通知一个空闲的装卸工(Worker 线程)去处理这辆车的装卸。这样,少量的司机和装卸工就能处理海量的货物。

结论:Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能服务器和客户端。它极大地简化了网络编程,让你不用从底层 Socket 开始苦苦折腾。

入门

基于 Netty 框架的简单客户端 - 服务器通信功能

基本目录:

在这里插入图片描述

其中:

java/
└── com/└── netty/├── NettyClient.java       // 客户端启动类├── NettyServer.java       // 服务端启动类├── client/                // 客户端相关组件│   ├── ClientInitializer.java  // 客户端 Channel 初始化器│   └── ClientHandler.java      // 客户端业务处理器└── server/                // 服务端相关组件├── ServerInitializer.java  // 服务端 Channel 初始化器└── ServerHandler.java      // 服务端业务处理器

服务器功能

public class ServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {// 此时msg已经被解码器转为String,无需手动释放String in = (String) msg;System.out.println("Server 接收: " + in);// 直接发送字符串,编码器会自动转为ByteBufString response = "Hello from server!";ctx.writeAndFlush(response);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}
public class ServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();// 添加字符串解码器pipeline.addLast(new StringDecoder());// 添加字符串编码器pipeline.addLast(new StringEncoder());// 添加自定义的处理器pipeline.addLast(new ServerHandler());}}
public class NettyServer  {public static void main(String[] args)  throws InterruptedException {EventLoopGroup bossGroup = new NioEventLoopGroup();//处理连接请求EventLoopGroup workerGroup = new NioEventLoopGroup();//处理读写事件try {// 创建服务器启动引导类ServerBootstrap b = new ServerBootstrap();// 配置服务器参数b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)          // 使用NIO传输通道.childHandler(new ServerInitializer());         // 设置业务处理器// 绑定端口并启动服务器ChannelFuture f = b.bind(8080).sync();System.out.println("Server started on port 8080");// 等待服务器通道关闭f.channel().closeFuture().sync();} finally {// 关闭EventLoopGroupworkerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}
}
  • 监听本地 8080 端口
  • 接收客户端发送的字符串消息并打印
  • 收到消息后,向客户端返回 “Hello from server!” 响应

客户端功能

public class ClientHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {// 直接发送字符串,编码器会自动转为ByteBufString msg = "Hello from client!";ctx.writeAndFlush(msg);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {// 此时msg已经被解码器转为StringString in = (String) msg;System.out.println("Client 接收: " + in);ctx.close();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}
public class ClientInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new StringDecoder());pipeline.addLast(new StringEncoder());pipeline.addLast(new ClientHandler());}
}
public class NettyClient {public static void main(String[] args) throws InterruptedException {// 创建EventLoopGroup实例EventLoopGroup group = new NioEventLoopGroup();  // 处理I/O操作和业务逻辑try {// 创建客户端启动引导类Bootstrap b = new Bootstrap();// 配置客户端参数b.group(group).channel(NioSocketChannel.class)           // 使用NIO套接字通道.handler(new ClientInitializer());         // 设置业务处理器// 连接服务器ChannelFuture f = b.connect("localhost", 8080).sync();// 等待连接关闭f.channel().closeFuture().sync();} finally {// 优雅关闭EventLoopGroupgroup.shutdownGracefully();}}
}
  • 连接本地 8080 端口的服务器
  • 连接成功后向服务器发送 “Hello from client!” 消息
  • 接收服务器返回的响应消息并打印
  • 完成通信后关闭连接

时间线:

  1. 客户端连接服务器 (TCP握手完成)
  2. 客户端 channelActive() 触发 → 发送 “Hello from client!”
  3. 服务器收到数据 → channelRead() 触发 → 发送 “Hello from server!”
  4. 客户端收到响应 → channelRead() 触发 → 关闭连接

在这里插入图片描述

在这里插入图片描述

在这其中,Netty起作用如下:

代替原生 Java NIO:

// Netty 封装了复杂的 NIO 操作
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)  // Netty 提供的 NIO 通道实现.handler(new ClientInitializer());

提供现成的编解码器:

pipeline.addLast(new StringDecoder());  // 字节 → 字符串
pipeline.addLast(new StringEncoder());  // 字符串 → 字节

事件模型:

public class ClientHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) {// 连接建立时自动回调}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {// 收到数据时自动回调}
}

管道机制:

ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder());    // 处理器1:解码
pipeline.addLast(new StringEncoder());    // 处理器2:编码  
pipeline.addLast(new ServerHandler());    // 处理器3:业务逻辑

ByteBuf:

// 底层使用 Netty 的高效缓冲区
// StringEncoder 自动将 String 转换为优化的 ByteBuf
ctx.writeAndFlush(response);

自动处理:

  • TCP 连接的建立和维护
  • 连接的超时和重连
  • 优雅的关闭和资源释放
// Netty 自动管理连接生命周期
ChannelFuture f = b.bind("localhost", 8080).sync();
f.channel().closeFuture().sync();

感谢阅读>W<


文章转载自:

http://2IXwkzFI.Lssfd.cn
http://tB6BaiFh.Lssfd.cn
http://AUxRujWs.Lssfd.cn
http://TXsdAH7U.Lssfd.cn
http://2O7HsItK.Lssfd.cn
http://FYm3BF82.Lssfd.cn
http://O3ufWp9L.Lssfd.cn
http://D6mWf8kw.Lssfd.cn
http://PQFItR4a.Lssfd.cn
http://Lq0ZBmxQ.Lssfd.cn
http://tyhSiJzv.Lssfd.cn
http://vADM9Z8m.Lssfd.cn
http://JavcoALB.Lssfd.cn
http://cMf4rEzT.Lssfd.cn
http://rT4TVDYu.Lssfd.cn
http://TlTzHl7F.Lssfd.cn
http://V6HVyM2Y.Lssfd.cn
http://6FZtt4SG.Lssfd.cn
http://ViiFCm5G.Lssfd.cn
http://K7xFD7Da.Lssfd.cn
http://LsUKXLmU.Lssfd.cn
http://cDtd1dTX.Lssfd.cn
http://62Lx7LS9.Lssfd.cn
http://a5gZPfRr.Lssfd.cn
http://pO2AuwHR.Lssfd.cn
http://jrkrZNgb.Lssfd.cn
http://vrFtWg8o.Lssfd.cn
http://gbpBBAyb.Lssfd.cn
http://dZm0dp2D.Lssfd.cn
http://UhdDWNrv.Lssfd.cn
http://www.dtcms.com/a/379173.html

相关文章:

  • VGGNet:为什么16层简单堆叠能成为CNN经典?
  • 知识图谱RAG
  • 与controller层的接口入参注解@Valid有关的实体类判断空的注解
  • 基于AT89C52单片机的智能蓝牙台灯设计
  • Javaweb前端内容的思维导图
  • PyTorch深度学习实战【10】之神经网络的损失函数
  • 3.前置知识学习
  • Whois查询域名信息
  • 机器学习vs人类学习:人类学习如何借鉴机器学习方法?
  • ES6 面试题及详细答案 80题 (41-54)-- 异步编程(Promise/Generator/async)
  • Bug记录:Lombok @Builder 注解的两大陷阱及解决方案
  • ARM汇编 beep及bsp工程管理
  • 深入理解 Vue3 Router:三种路由模式的工作原理与实战应用
  • 2025 ICPC Gran Premio de Mexico 3ra Fecha
  • ZLMediaKit性能测试
  • 使用PyQt5和NumPy从TXT文件读取平面点集数据
  • nacos1.3.2 ARM 版容器镜像制作
  • LINUX中Docker Swarm的介绍和使用
  • 探索大语言模型(LLM):Ollama快速安装部署及使用(含Linux环境下离线安装)
  • 安卓13_ROM修改定制化-----打开摄像头调用相机功能 实现无人直播
  • 嵌入式 - ARM5
  • 如何打造自主安全的下一代域名系统
  • 前端开发工具有哪些?常用前端开发工具、前端调试工具、前端构建工具与效率提升工具对比与最佳实践
  • 机器学习1.Anaconda安装+环境配置
  • GrapeCity Documents V8.0 Update2 重磅发布:性能飞跃、AI 赋能与文档处理全流程升级
  • 【软考架构-案例分析】质量属性场景描述6要素
  • IBMS智能化集成系统:构建建筑全场景协同管控中枢
  • 【高级】系统架构师 | 2025年上半年综合真题DAY4
  • 系统接口故障排查
  • MyBatis框架(编写代码部分1)