Netty4自学笔记 (3) - Netty NIO Server和Client 样例说明

全文详见个人独立博客:Netty4自学笔记 (3) - Netty NIO Server和Client 样例说明

Netty4自学笔记 (3) - Netty NIO Server和Client 样例说明更新节奏缓慢,因为每晚学习注意力不够集中,学习进展缓慢。本还给自己找了一大堆其他理由,但摸着良心问自己,似乎只有这个理由说的通。 想搞懂的太多,却始终没搞明白。先看一个用Netty编写的NIO Server的样例。 package com.coderli.nettylab.guide; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * @author lihongzhe 2018/7/24 23:19 */ public class NettyNioServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); // (2) b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) // (3) .childHandler(new ChannelInitializer<SocketChannel>() { // (4) @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture f = b.bind(7060).sync(); // (5) f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } } ServerHanler代码 package com.coderli.nettylab.guide; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * @author lihongzhe 2018/7/24 23:58 */ public class ServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { System.out.println("Receive Msg."); ((ByteBuf) msg).release(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } } 上述代码改自Netty官方手册。NettyNioServer代码中做了几处标记,分别对应我们在Netty4 自学笔记(2)中讨论的关键点,简析如下: 标记1是构建了两个线程池,我们在Java NIO学习中提到的,针对Select的实现方式,如果想要实现并发,只需要在事件处理时,启用多线程处理即可,此处的workerGroup正是为此服务。而在Netty中,不仅仅对于事件到达后的处理启用了线程池,为了实现高并发,Netty开启多个线程注册多个Selector同时处理事件。Netty中,默认线程池数量为,cpu核心数 * 2(NettyRuntime.availableProcessors() * 2),个人认为Selector线程数过多意义也不大,关键还是在于事件分发后的后续处理,即work线程。同样,这里worker线程池的默认数量与boss一致,因此在业务实现中应注意异步处理worker中的回调,以免堵塞worker,影响并发。 标记2的ServerBootstrap是Netty封装的统一配置并启动Server的启动器,在Java NIO学习中提到的Channel(标记3)和事件处理器Handler(标记4),都统一配置在此。标记3处指定不同类型的Channel(例如:Nio、Oio),底层便可方便的在不同的通信模式下进行切换,上层无感知。 标记5,一切配置好后,启动器绑定到指定端口。 从样例代码的直观感觉来说,Netty提供了良好的封装,无论是Server还是事件处理的Handler,Netty几乎帮我们做好了一切。对于开发人员来说,只需要关注于Netty提供的Handler的回调时机,开发自己的业务逻辑,比直接使用Java NIO的API节约了很多的开工作量,而且保证了代码的健壮性和多线程支持。 因此,我下一步的思路就是去研究一下Netty中Handler的回调机制,真正掌握才可开发逻辑正确的代码。 本文的最后,把Client端的代码补充完整,以便调试, NettyNioClient package com.coderli.nettylab.guide; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; /** * @author lihongzhe 2018/8/6 22:55 */ public class NettyNioClient { public static void main(String[] args) throws InterruptedException { EventLoopGroup workerGroup = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class); b.option(ChannelOption.SO_KEEPALIVE, true); b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ClientHandler()); } }); ChannelFuture f = b.connect("127.0.0.1", 7060).sync(); // Wait until the connection is closed. f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); } } } ClientHandler package com.coderli.nettylab.guide; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import java.util.Date; /** * @author lihongzhe 2018/8/6 23:13 */ public class ClientHandler extends ChannelInboundHandlerAdapter { private ByteBuf buf; @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { System.out.println("Channel Registered, Client."); ctx.fireChannelRegistered(); } @Override public void handlerAdded(ChannelHandlerContext ctx) { System.out.println("Handler added."); buf = ctx.alloc().buffer(4); } @Override public void handlerRemoved(ChannelHandlerContext ctx) { buf.release(); buf = null; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf m = (ByteBuf) msg; buf.writeBytes(m); m.release(); if (buf.readableBytes() >= 4) { long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L; System.out.println(new Date(currentTimeMillis)); ctx.close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } } 后续的研究,我也会基于上述代码加以改造和调试。icon-default.png?t=N7T8https://www.coderli.com/netty4-3-netty-server-client-demo/

欢迎加入群聊,一起交流探讨:【Java学习交流(982860385)】 

更新节奏缓慢,因为每晚学习注意力不够集中,学习进展缓慢。本还给自己找了一大堆其他理由,但摸着良心问自己,似乎只有这个理由说的通。

想搞懂的太多,却始终没搞明白。先看一个用Netty编写的NIO Server的样例。

package com.coderli.nettylab.guide;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;/*** @author lihongzhe 2018/7/24 23:19* @site https://www.coderli.com*/
public class NettyNioServer {public static void main(String[] args) throws InterruptedException {EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap(); // (2)b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // (3).childHandler(new ChannelInitializer<SocketChannel>() { // (4)@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new ServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);ChannelFuture f = b.bind(7060).sync(); // (5)f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}}

ServerHanler代码

package com.coderli.nettylab.guide;import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** @author lihongzhe 2018/7/24 23:58* @site https://www.coderli.com*/
public class ServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {System.out.println("Receive Msg.");((ByteBuf) msg).release(); }@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

上述代码改自Netty官方手册。NettyNioServer代码中做了几处标记,分别对应我们在Netty4 自学笔记(2)中讨论的关键点,简析如下:

 全文详见个人独立博客:

Netty4自学笔记 (3) - Netty NIO Server和Client 样例说明

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

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

相关文章

适用于个人使用的十大数据恢复工具:综合指南

有许多数据恢复工具和软件可用于帮助恢复丢失或损坏的文件。通过了解您的需求并考虑这里探讨的工具&#xff0c;您将能够选择最佳的数据恢复软件&#xff0c;并希望找回您丢失的宝藏。在本综合指南中&#xff0c;我们将探索个人使用的十大数据恢复工具&#xff0c;重点介绍它们…

自定义CustomRatingBar控件

通过自定义RatingBar的样式实现⭐️⭐️⭐️指示器的方式功能过于受限&#xff0c;而且显示的样式阴影会受到影响。 系统自带显示&#xff1a; 自定义样式&#xff1a; 因此简单自一个符合要求的 CustomRatingBar 支持设置星星数量支持设置星星Rating(float)支持设置空显示…

NICE Seminar(2023-07-16)|演化算法的理论研究到底有什么用?(南京大学钱超教授)

模式定理&#xff08;Schema Theorem&#xff09; 模式定理&#xff08;Schema Theorem&#xff09;是遗传算法&#xff08;Genetic Algorithm, GA&#xff09;的重要理论基础&#xff0c;由约翰霍兰德&#xff08;John Holland&#xff09;在1975年提出。它描述了具有特定模式…

CSS mask-image 实现边缘淡出过渡效果

使用场景 在生产环境中&#xff0c;遇到一个需求&#xff0c;需要在一个深色风格的大屏页面中&#xff0c;嵌入 Google Maps。为了减少违和感&#xff0c;希望地图四边能够淡出过渡。 这里的“淡出过渡”&#xff0c;关键是淡出&#xff0c;而非降低透明度。 基于 Google Ma…

Tecplot安装error找不到指定模块之解决方案

最近有小伙伴反应&#xff0c;在安装Tecplot 2023版本时&#xff0c;参考教程来操作很顺利&#xff0c;但是在开启软件后&#xff0c;有一个error弹窗&#xff0c;内容如下&#xff1a; 随后用中英文翻译&#xff1a;找不到指定模块 同时&#xff0c;软件内部的Tool工具栏打不…

大路灯护眼灯有必要买吗?五款护眼大路灯推荐

大路灯护眼灯有必要买吗&#xff1f;许多消费者对护眼大路灯的了解不够&#xff0c;总是被不专业产品“耍”得团团转。就比如市面上很多声称用了眼睛就不近视的产品&#xff0c;实际上它们毫无专业技术沉淀&#xff0c;还疏于调校光线稳定性、光线均匀度等上百项核心参数&#…

基于IOT架构的数据采集监控平台!

LP-SCADA数据采集监控平台是蓝鹏测控推出的一款聚焦于工业领域的自动化数据采集监控系统&#xff0c; 助力数字工厂建设的统一监控平台。 为企业提供从下到上的完整的生产信息采集与集成服务&#xff0c;从而为企业综合自动化、工厂数字化及完整的"管控一体化”的解决方案…

校园水电费管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;宿舍信息管理&#xff0c;学生缴费管理&#xff0c;教师缴费管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;我的 开发系统…

抖音视频素材一般都从哪里找?抖音视频素材库分享

在浏览抖音时&#xff0c;你是否曾被那些内容丰富、制作精良的视频所吸引&#xff1f;这些视频背后的秘密其实非常简单——高质量的视频素材。优质素材能够让你的视频更加出彩。然而&#xff0c;许多抖音内容创作者在初期可能会困惑&#xff1a;这些视频素材究竟从哪里获取呢&a…

linux uos悬浮窗口置顶问题

问题背景 公司软件有一个功能&#xff0c;在PPT播放时&#xff0c;我们软件悬浮窗口需要在WPS幻灯片上层显示&#xff0c;方便客户操作按钮。在window 上我们设置了窗口的topmost 所以能够显示在最前面。如下图所示&#xff1a; 但是在软件适配国产操作系统Linux统信和麒麟在w…

推动未来的引擎:人工智能大模型的现状与发展

推动未来的引擎&#xff1a;人工智能大模型的现状与发展 一、引言 随着人工智能技术的迅速发展&#xff0c;人工智能大模型作为其中的重要组成部分&#xff0c;正逐渐成为推动科技进步的重要引擎。无论是在自然语言处理、计算机视觉&#xff0c;还是智能推荐等领域&#xff0…

Python酷库之旅-第三方库Pandas(061)

目录 一、用法精讲 236、pandas.Series.explode方法 236-1、语法 236-2、参数 236-3、功能 236-4、返回值 236-5、说明 236-6、用法 236-6-1、数据准备 236-6-2、代码示例 236-6-3、结果输出 237、pandas.Series.searchsorted方法 237-1、语法 237-2、参数 237-…

Kubernetes 学习记录

https://note.youdao.com/ynoteshare/index.html?idbc7bee305611b52d6900ba209a92bd4d&typenote&_time1694072007342 概览 K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ K8S 是Kubernetes的全称&#xff0c;源于希腊语&#xff0c;意为“舵手”或“…

江科大/江协科技 STM32学习笔记P17

文章目录 一、TIM输入捕获输入捕获与输出比较的关系频率测量测频法测周法 输入捕获的电路异或门的执行逻辑 输入捕获通道主从触发模式输入捕获基本结构PWMI基本结构输入捕获模式测频率main.c 输入捕获模式测占空比main.c 一、TIM输入捕获 输入捕获与输出比较的关系 在输出比较中…

PMP--冲刺--易混概念

文章目录 十大知识领域一、整合管理项目管理计划与项目文件的区分&#xff1a; 二、范围管理三、进度管理赶工与快速跟进的区分&#xff1a;赶工增加资源&#xff0c;以最小的成本代价来压缩进度工期&#xff1b;快速跟进&#xff0c;将正常情况下按顺序进行的活动或阶段改为至…

秋招突击——算法训练——8/1——用友集团笔试

文章目录 引言正文小友的生产线个人实现参考实现 小友策划游戏人物个人实现参考实现 最佳工作任务安排个人实现参考实现 大众评分最高的一次旅程 总结 引言 今天晚上七点钟到九点钟是用友集团的笔试&#xff0c;作为今天算法练习的主要内容&#xff01;具体怎么样&#xff0c;…

Python练习2

文章目录 主要内容一.Python基础练习题1.密码验证合格程序代码如下&#xff08;示例&#xff09;: 2.两数之和代码如下&#xff08;示例&#xff09;: 3.字符个数统计代码如下&#xff08;示例&#xff09;: 总结 主要内容 Python基础练习题 一.Python基础练习题 1.密码验证合…

频率的工程测量01 - Rif算法的构造

1.原始文档 《用于正弦波频率估计的修正I-Rife算法》&#xff0c;王哲文&#xff0c;2024 DOI&#xff1a; 10. 16337/j. 1004‑9037. 2024. 02. 019 1.1 这篇论文所属的自科基金U21A20500&#xff1a;近5年所承担的重要科研项目表-智能感知系统与安全教育部重点实验室&#…

lua学习(1)

vscode打开c或者lua文件 插件显示禁用&#xff0c;怎么开启插件。 1. lua 字符串 单个引号和双引号都可变量的定义默认是全局的删除一个变量将其赋值为nil即可 如&#xff1a; bnilnil还可以对表中的数据进行删除&#xff0c;也可删除一个表只要变量不是nil&#xff0c;变…

c语言第七天笔记

作业题&#xff1a; 设计TVM&#xff08;地铁自动售票机&#xff09;机软件。 输入站数&#xff0c;计算费用&#xff0c;计费规则&#xff0c;6站2元&#xff0c;7-10站3元&#xff0c;11站以上为4元。 输入钱数&#xff0c;计算找零(找零时优先找回面额大的钞票)&#xff0…