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

news2024/11/15 6:49:00

全文详见个人独立博客: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)
                        @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
 * @site https://www.coderli.com
 */
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)中讨论的关键点,简析如下:

 全文详见个人独立博客:

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

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

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

相关文章

tof系统标定流程之双频测距与代码详解

tof系统标定流程之双频测距目录 1、双频测距原理2、双频测距流程3、双频测距代码1、双频测距原理 为什么需要双频测距,只用一个频率测距不行吗?实际上一个频率的测距范围有限,以100MHZ/80MHZ/10MHZ/15MHZ的频率为例,其测距范围分别是1.5m,1.875m,15m,10m,频率越低测距范围…

TypeError: ‘dict’ object is not callable 深度解析

TypeError: ‘dict’ object is not callable 深度解析 在Python编程中&#xff0c;TypeError: dict object is not callable是一个常见的错误&#xff0c;通常发生在尝试调用一个字典对象时。这个错误表明代码中存在逻辑错误&#xff0c;可能是将字典误用为函数或方法。本文将…

C++第六篇 模板初阶和STL简介

目录 一&#xff0c;模板初阶 1.泛型编程 2.函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3.类模板(模板类&#xff0c;模板函数) 3.1 类模板定义格式 二&#xff0c;STL简介 1. 什么是STL 2. ST…

[环境配置]Pycharm:Failed to start [PowerShell.exe]

解决方法&#xff0c;点Local旁边的 号&#xff0c;点击Command Prompt&#xff0c;即可在Pycharm中呼出控制台。 如果要修改Command Prompt的启动时访问的cmd.exe的路径&#xff0c;可以去Settings→Tools→Terminal中&#xff0c;修改Shell Path实现&#xff0c;改为cmd.exe…

「AI绘画Stable Diffusion 零基础入门 」AI 绘画SD原理与工具介绍,万字详解新手入门必看!

大家好&#xff0c;我是设计师阿威 AI 绘画原理 想要入门 AI 绘画&#xff0c;首先需要了解它的原理是什么样的。 其实很早就已经有人基于深度学习模型展开了对图像生成的研究了&#xff0c;但在那时&#xff0c;生成的图像分辨率和内容都非常抽象。 直到近两年&#xff0c…

CentOS 8挂载本地源

CentOS 8挂载本地源 1.虚拟机连接centos镜像2.系统查看centos镜像是否在连接上3. 挂载ISO镜像4.配置YUM源1. 备份现有YUM源配置2. 创建新的YUM源配置文件3. 清理YUM缓存并重新生成 5.验证YUM源 1.虚拟机连接centos镜像 2.系统查看centos镜像是否在连接上 [rootlocalhost ~]# l…

【wiki知识库】07.用户管理后端SpringBoot部分

目录 一、今日目标 二、&#x1f388;SpringBoot部分类的添加 2.1 使用逆向工程新增User模块 2.2 UserQueryParam添加 2.3 UserSaveParam添加 2.4 UserResetPasswordParam添加 2.5 UserQueryVo添加 2.6 SnowFlake工具类 三、&#x1f686;后端新增接口 3.1 /user/li…

【应用层】远程登入管理设备 Telnet

文章目录 Telnet 概述Telnet 认证模式用户等级eNSP 搭建拓扑验证password认证方式登入&#xff08;不支持空密码登入&#xff09;AAA认证方式登入 eNSP连接真机环境配置telnetTelnet 配置命令汇总 Telnet 概述 Telnet是一种基于文本的网络协议&#xff0c;它允许用户通过虚拟终…

PHP开发【石头剪刀布小游戏】

石头剪刀布小游戏 玩法超级简单&#xff0c;你只需要在下面选择石头、剪刀或者布&#xff0c;然后提交&#xff0c;系统就会随机生成电脑的选择&#xff0c;告诉你最终的结果哦&#xff01; 游戏规则&#xff1a; 如果你的选择和电脑一样&#xff0c;那么就是平局。如果你赢…

十一、外观模式

文章目录 1 基本介绍2 案例2.1 Person 类2.2 Computer 类2.3 Player 类2.4 TV 类2.5 StudyManager 类2.6 Client 类2.7 Client 类运行结果2.8 总结 3 各角色之间的关系3.1 角色3.1.1 SubSystem ( 子系统 )3.1.2 Facade ( 窗口 )3.1.3 Client ( 客户端 ) 3.2 类图 4 注意事项5 在…

PointNet点云语义分割

在本教程中&#xff0c;我们将学习如何在斯坦福 3D 室内场景数据集 (S3DIS) 上训练 Point Net 进行语义分割。S3DIS 是一个 3D 数据集&#xff0c;包含来自多栋建筑的室内空间点云&#xff0c;占地面积超过 6000 平方米 [1]。Point Net 是一种新颖的架构&#xff0c;它使用整个…

基于JAVA的陶瓷工厂进销存管理系统的设计与实现

点击下载源码 基于JAVA的陶瓷工厂进销存管理系统的设计与实现 摘 要 时代在进步&#xff0c;我们的生产生活方式当然也要相对应的做出改变了。在今天这样一个信息化的时代&#xff0c;计算机软件已经广泛的被用于日常的办公&#xff0c;仓库的库存管理&#xff0c;企业的人员…

2024年热门开放式耳机评测!悠律、韶音、声阔到底该选谁?

开放式耳机选购技巧篇&#xff0c;可参考选购&#xff01; 作为一名数码评测博主&#xff0c;这两年用过的开放式耳机不下50款了&#xff0c;市面上的开放式耳机众多&#xff0c;很多人不知道该如何选择&#xff0c;其实选购都是有一定的技巧和规律性的&#xff0c;看配置就能…

无损下载器1.1.0.0(3.6M)支持批量下载无损音乐

无损音乐下载器。只有3.6M&#xff0c;简单试了一下感觉非常好用&#xff0c;不知道论坛里发过没有&#xff0c;也不知道作者是谁&#xff0c;非常感谢该软件的开发者&#xff01; 软件标题&#xff1a;无损下载器 版本号&#xff1a;1.1.0.0 使用步骤&#xff1a; 我们下载…

AVL解析

本节主要看板书 概念 AVL树&#xff08;Adelson-Velsky and Landis tree&#xff09;是一种自平衡二叉查找树&#xff0c;用于在动态集合中进行高效的插入、删除和查找操作。它保持树的高度接近最小可能值&#xff0c;从而确保这些操作的时间复杂度始终保持在O(log n)。AVL树…

OS—磁盘和固态硬盘

目录 一. 磁盘二. 磁盘的管理磁盘初始化分区引导块坏块 三. 磁盘调度算法磁盘存取时间磁盘调度算法先来先服务&#xff08;FCFS&#xff09;算法最短寻道时间优先&#xff08;Shorted Seek Time First,SSTF&#xff09;算法扫描&#xff08;SCAN&#xff09;算法LOOK 调度算法循…

30个可以帮程序员查询很多真相的网址

具体请前往&#xff1a;一站式综合查询导航 - 快递物流查询,国际区号查询,车牌号查询,航班动态查询,教育考试成绩和证书、学历、食品药品标准,招投标,知识产权,专利文献,企业信用,法律文书在线查询

13. 基于标定板的lidar到车体的外参标定思路

目录 1. 什么是lidar到车体的外参&#xff1f;2. 为什么要做这个外参矫正&#xff1f;3. 怎么做这个外参矫正&#xff1f;3.1 标定思路3.2 lidar检测标定板上的圆心流程介绍3.3 匹配过程 4. 老乡别走&#xff0c;一起来读书吧 1. 什么是lidar到车体的外参&#xff1f; 在机器人…

猫头虎分享疑难杂Bug:ERROR: No matching distribution found for beautifulsoup4解决方案

&#x1f42f; 猫头虎分享疑难杂Bug&#xff1a;ERROR: No matching distribution found for beautifulsoup4解决方案 摘要 Python开发过程中&#xff0c;ERROR: No matching distribution found for beautifulsoup4 是常见错误之一。本文将详细介绍此错误的产生原因及解决方…

2024最详细的安装教程来了!手把手教你安装Python和PyCharm

最详细的Python安装教程 一、进入Python官网首页&#xff0c;下载最新的Python版本 https://www.python.org/downloads/ 选择最新的Python3.10.5&#xff0c;下载64位的版本 二、下载完成后&#xff0c;进行安装 1.双击Python-3.10.5-amd64.exe 2.选择Customize installation…