Netty 全网最详细的教程! 没有之一!

2023-11-15

Netty 入门

入门案例

1、服务器端代码
public class HelloServer {
    public static void main(String[] args) {
        // 1、启动器,负责装配netty组件,启动服务器
        new ServerBootstrap()
                // 2、创建 NioEventLoopGroup,可以简单理解为 线程池 + Selector
                .group(new NioEventLoopGroup())
                // 3、选择服务器的 ServerSocketChannel 实现
                .channel(NioServerSocketChannel.class)
                // 4、child 负责处理读写,该方法决定了 child 执行哪些操作
            	// ChannelInitializer 处理器(仅执行一次)
            	// 它的作用是待客户端SocketChannel建立连接后,执行initChannel以便添加更多的处理器
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        // 5、SocketChannel的处理器,使用StringDecoder解码,ByteBuf=>String
                        nioSocketChannel.pipeline().addLast(new StringDecoder());
                        // 6、SocketChannel的业务处理,使用上一个处理器的处理结果
                        nioSocketChannel.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
                                System.out.println(s);
                            }
                        });
                    }
                    // 7、ServerSocketChannel绑定8080端口
                }).bind(8080);
    }
}Copy
2、客户端代码
public class HelloClient {
    public static void main(String[] args) throws InterruptedException {
        new Bootstrap()
                .group(new NioEventLoopGroup())
                // 选择客户 Socket 实现类,NioSocketChannel 表示基于 NIO 的客户端实现
                .channel(NioSocketChannel.class)
                // ChannelInitializer 处理器(仅执行一次)
                // 它的作用是待客户端SocketChannel建立连接后,执行initChannel以便添加更多的处理器
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        // 消息会经过通道 handler 处理,这里是将 String => ByteBuf 编码发出
                        channel.pipeline().addLast(new StringEncoder());
                    }
                })
                // 指定要连接的服务器和端口
                .connect(new InetSocketAddress("localhost", 8080))
                // Netty 中很多方法都是异步的,如 connect
                // 这时需要使用 sync 方法等待 connect 建立连接完毕
                .sync()
                // 获取 channel 对象,它即为通道抽象,可以进行数据读写操作
                .channel()
                // 写入消息并清空缓冲区
                .writeAndFlush("hello world");
    }
}Copy
3、运行流程

左:客户端 右:服务器端

img

组件解释

  • channel 可以理解为数据的通道
  • msg 理解为流动的数据,最开始输入是 ByteBuf,但经过 pipeline 中的各个 handler 加工,会变成其它类型对象,最后输出又变成 ByteBuf
  • handler 可以理解为数据的处理工序
    • 工序有多道,合在一起就是 pipeline(传递途径),pipeline 负责发布事件(读、读取完成…)传播给每个 handler, handler 对自己感兴趣的事件进行处理(重写了相应事件处理方法)
      • pipeline 中有多个 handler,处理时会依次调用其中的 handler
    • handler 分 Inbound 和 Outbound 两类
      • Inbound 入站
      • Outbound 出站
  • eventLoop 可以理解为处理数据的工人
    • eventLoop 可以管理多个 channel 的 io 操作,并且一旦 eventLoop 负责了某个 channel,就会将其与channel进行绑定,以后该 channel 中的 io 操作都由该 eventLoop 负责
    • eventLoop 既可以执行 io 操作也可以进行任务处理,每个 eventLoop 有自己的任务队列,队列里可以堆放多个 channel 的待处理任务,任务分为普通任务、定时任务
    • eventLoop 按照 pipeline 顺序,依次按照 handler 的规划(代码)处理数据,可以为每个 handler 指定不同的 eventLoop

使用组件

EventLoop

package com.Netty.Netty;

import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @Author:nioliu
 * @DATE: 2021/9/9  14:27
 */
@Slf4j
public class TestEventLoop {
    public static void main(String[] args) {
        // 1. 创建事件循环组
        // 可以负责 io 事件, 普通任务, 定时任务(内部使用ScheduledThreadPool实现)
        // 默认使用MAX(1,电脑核心数*2)线程数
        NioEventLoopGroup group = new NioEventLoopGroup(4);
        // 普通任务, 定时任务
//        DefaultEventLoopGroup defaultEventLoopGroup = new DefaultEventLoopGroup();

        // 2. 获取下一个事件循环对象(相当于一个循环链表做轮询), 上面设置为4, 那么每4个为依次循环
        System.out.println(group.next());
        System.out.println(group.next());
        System.out.println(group.next());
        System.out.println(group.next());
        System.out.println(group.next());
        System.out.println(group.next());
        System.out.println(group.next());

        // 3. 执行普通任务
        group.next().submit(new Runnable() {
            @Override
            public void run() {
                log.debug("这是个普通任务");
            }
        });

        // 4. 执行定时循环任务
        group.next().scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("OK");
            }
        },3,10, TimeUnit.SECONDS);

        log.debug("main");

        // 优雅的关闭(任务全部执行完后关闭)
        group.shutdownGracefully();
    }
}
创建一个EventLoopServer
package com.Netty.Netty.Components;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;

/**
 * @Author:nioliu
 * @DATE: 2021/9/9  14:39
 */
@Slf4j
public class EventLoopServer {
    public static void main(String[] args) {
        new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                ByteBuf buffer = (ByteBuf) msg;
                                String s = buffer.toString(Charset.defaultCharset());
                                log.debug(s);
                            }
                        });
                    }
                }).bind(8080);
    }
}
创建一个Client
package com.Netty.Netty.Components;


import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;

/**
 * @Author:nioliu
 * @DATE: 2021/9/9  14:44
 */
public class EventLoopClient {
    public static void main(String[] args) throws InterruptedException {
        Channel channel = new Bootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel.pipeline().addLast(new StringEncoder());// 内部使用CharBuffer.wrap(msg)
                    }
                })
                .connect("localhost", 8080)
                .sync()
                .channel();
//                .writeAndFlush("我是nio");
        // 使用debug模式向服务器发送数据
        System.out.println(channel);
    }
}

在System.out.println(channel); 处打上断电, 并设置只切断当前Thread

使用Evaluate Expression工具进行信息发送(调用channel…writeAndFlush(“我是nio”)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Netty 全网最详细的教程! 没有之一! 的相关文章

  • 在文本文件中写入多行(java)

    下面的代码是运行命令cmd并使用命令行的输出生成一个文本文件 下面的代码在 Eclipse 的输出窗口中显示了正确的信息 但在文本文件中只打印了最后一行 谁能帮我这个 import java io public class TextFile
  • 如何创建一个显示 Spinners 的 x 和 y 值的表格?

    我想创建一个位于图表右侧的表格 其中显示 2 列 x 和 y 值已输入到xSpin and ySpin旋转器 我已经画了一张我想要桌子放置的位置的图 我尝试过在网格窗格布局中使用文本框来创建表格并将值直接输入到文本框网格中 但是我无法将它们
  • 使用 JPA Criteria API 进行分页的总行数

    我正在系统中为实体实现 高级搜索 功能 以便用户可以使用该实体的属性上的多个条件 eq ne gt lt 等 来搜索该实体 我正在使用 JPA 的 Criteria API 动态生成 Criteria 查询 然后使用setFirstResu
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Java AES 128 加密方式与 openssl 不同

    我们遇到了一种奇怪的情况 即我们在 Java 中使用的加密方法会向 openssl 生成不同的输出 尽管它们在配置上看起来相同 使用相同的键和 IV 文本 敏捷的棕色狐狸跳过了懒狗 加密为 Base64 字符串 openssl A8cMRI
  • 比较两个文本文件的最快方法是什么,不将移动的行视为不同

    我有两个文件非常大 每个文件有 50000 行 我需要比较这两个文件并识别更改 然而 问题是如果一条线出现在不同的位置 它不应该显示为不同的 例如 考虑这个文件A txt xxxxx yyyyy zzzzz 文件B txt zzzzz xx
  • wait() 在游戏中如何工作?

    在 playframework 的文档中here http www playframework org documentation 1 2 1 asynchronous已写 public static void loopWithoutBlo
  • 当从服务类中调用时,Spring @Transactional 不适用于带注释的方法

    在下面的代码中 当方法内部 是从内部调用的方法外部 应该在交易范围内 但事实并非如此 但当方法内部 直接从调用我的控制器class 它受到事务的约束 有什么解释吗 这是控制器类 Controller public class MyContr
  • Hibernate.createBlob() 方法从 Hibernate 4.0.1 开始已弃用,并移至 Hibernate.getLobCreator(Session session).createBlob()

    Method Hibernate createBlob 已弃用自休眠4 0 1并搬到Hibernate getLobCreator Session session createBlob 任何解决方案我应该在方法内传递什么getLobCrea
  • 普罗米修斯指标 - 未找到

    我有 Spring Boot 应用程序 并且正在使用 vertx 我想监控服务和 jvm 为此我选择了 Prometheus 这是我的监控配置类 Configuration public class MonitoringConfig Bea
  • react-native run-android 失败并出现错误:任务 ':app:dexDebug' 执行失败

    我使用的是 Windows 8 1 和react native cli 1 0 0 and react native 0 31 0 添加后react native maps对于该项目 我运行了命令react native upgrade并给
  • 如何在selenium服务器上提供自定义功能?

    我知道可以通过某种方法获得一些硒功能 其中之一如下 driver getCapabilities getBrowserName 它返回浏览器名称的值 但如果它指的是一个可用的方法 如果我没有误解的话 这似乎与自定义功能有关 就像我的意思是
  • IntelliJ - 调试模式 - 在程序内存中搜索文本

    我正在与无证的第三方库合作 我知道有一定的String存储在库深处的某个字段中的某处 我可以预测的动态值 但我想从库的 API 中获取它 有没有一种方法可以通过以下方式进行搜索 类似于全文搜索 full程序内存处于调试模式并在某个断点处停止
  • 测试弱引用

    在 Java 中测试弱引用的正确方法是什么 我最初的想法是执行以下操作 public class WeakReferenceTest public class Target private String value public Targe
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • 替换后增量

    我自己已经有一个问题了 但我想扩展它后增量示例 https stackoverflow com questions 51308967 post increment with example char a D int b 5 System o
  • spring中如何使用jackson代替JdkSerializationRedisSerializer

    我在我的一个 Java 应用程序中使用 Redis 并且正在序列化要存储在 Redis 中的对象列表 但是 我注意到使用 RedisTemplate 会使用 JdkSerializationRedisSerializer 相反 我想使用 J
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • 如何从 Maven 存储库引用本机 DLL?

    如果 JAR 附带 Maven 存储库中的本机 DLL 我需要在 pom xml 中放入什么才能将该 DLL 放入打包中 更具体地举个例子Jacob http search maven org artifactdetails 7Cnet s

随机推荐

  • 电脑提示vcruntime140_1.dll缺少怎么办?

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或者损坏了 这时你只需下载这个vcruntime140 1 dll文件进行安装
  • Alpaca构建方式探秘:低成本构造指令数据增强LLM

    官方介绍 Alpaca A Strong Replicable Instruction Following Model github地址 https github com tatsu lab stanford alpaca Alpaca简介
  • 【STL】list容器的插入与删除

    STL list容器插入与删除 添加或插入新元素 list成员方法 push front 向 list 容器首个元素前添加新元素 push back 向 list 容器最后一个元素后添加新元素 emplace front 在容器首个元素前直
  • 基于LSTM、BP神经网络实现电力系统负荷预测(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 LSTM 2 2 BP 3 Python代码及数据 4 参考文献 1 概述 前馈神经
  • JavaSE加强知识

    tips 在Java中 万物皆对象 不然我们的Java就白学了 本栏文章我们将会陆续上传以下知识 static 单例 代码块 继承 面向对象五大金刚 成员变量 方法 代码块 构造器 内部类 权限修饰符 抽象类 接口 多态 内部类 常用API
  • DDR3 终端参考电阻 rzq

    https blog csdn net chenzhen1080 article details 82951214 问题1 ddr3侧 的参考电阻和 FPGA侧 的参考电阻是不是同一个功能 同一个阻值 DDR3 器件上 要标配 240 参考
  • SGMD辛几何模态分解

    将时间序列分解为一组独立的模态分量 模态混叠情况大幅度降低 SGMD利用辛几何相似度变换来求解哈密顿矩阵的特征值 并利用其 相应的特征向量来重构单分量信号 同时 SGMD可以在没有任何用户定义参数的情况下 有效地重构现有的模式 去除噪声 该
  • Halcon中数据的四舍五入、取整、有效数字以及和字符串之间的转换

    a 3 456 取整 取最近的整数 int a int a 取整数部分 结果是3 round a round a 将输入元组转换为最接近的整数元组 结果是3 四舍五入 结果是字符串 g0 a 0f 保留0位 结果是 3 g1 a 1f 保留
  • js延迟操作

    在写前端代码的时候需要实现某些交互操作 有些效果需要停顿几秒再实现 这时可以用到下面的方法 setTimeout function 5秒后实现的方法写在这个方法里面 5 1000 延迟5000毫秒
  • 第15届全国大学生知识竞赛 2022ciscn初赛 部分wp

    Misc ez usb 1 键盘流量 USB协议数据部分在Leftover Capture Data域中 数据长度为八个字节 其中键盘击键信息集中在第三个字节中 如图 发现击键信息为0x06 即对应的按键为C 2 鼠标流量 USB协议鼠标数
  • 并发编程-Linux环境下C语言并发理解-一

    在centos7上安装gcc 使用yum命令安装还是非常easy的 yum y install gcc gcc c kernel devel 安装gcc c 编译器以及内核文件 使用VI工具编写如下代码 include
  • openssl命令基础用法:哈希

    单向加密需要使用的标准命令为 dgst 用法如下 openssl dgst md5 md4 md2 sha1 sha mdc2 ripemd160 dss1 c d hex binary out filename sign filename
  • 微信小程序项目:粤语教学平台-粤言粤语

    文章目录 1 项目简介 1 1 创意来源 1 2选题意义 2 总体设计 2 1 系统功能 2 1 1 功能概述 2 1 2 功能说明 2 2 系统软硬件平台 2 3 关键接口技术 2 4 作品特色 3 详细设计 3 1 系统结构设计 3 1
  • error C2666: “QByteRef::operator ==”: 2 个重载有相似的转换

    出现这样的问题 就是语法出现问题 以下写就是错的 以下写的就是解决了问题
  • 树莓派使用上spi tft!(fbtft的使用)

    关于树莓派的视频输出除了HDMI和 VNC基本上没有其他的方法 如果你手上刚好有一块TFT模块的话就可以当做系统显示屏 framebuff 虽然分辨率不高 但足以满足一些cmd的需求 github上项目 notro fbtft 很好的实现了
  • MyBatis使用resultMap解决1对多关联映射

    案例 查询MySQL中user表和orders表所有用户信息及用户关联的订单信息 用户信息和订单信息为一对多关系 SELECT u id u username u birthday u sex u address o id oid o nu
  • httprunner startproject.....报错

    httprunner新版本新建框架报错 问题 一开始报 cmd命令输入 httprunner startproject demo cmd结果显示 usage httprunner h V run make 我尝试降低到V2的版本 后面直接输
  • VMware虚拟机添加新硬盘

    在windows Server 2008 R2虚拟机配置中新加一块硬盘 首先在主机配置界面 打开虚拟主机设置 gt 添加一个新的硬盘组件 gt 选择磁盘接口类型 gt 创建新磁盘 gt 分配磁盘空间 gt 下一步安装 具体操作流程看下图 注
  • ARMV8体系结构简介:AArch64系统级体系结构之编程模型(3)- 异常

    1 前言 本文介绍异常相关内容 包括异常类型 异常进入 异常返回 异常层次结构 异常的路由等 2 RESET ARMV8体系结构支持两种类型的RESET Cold reset Reset PE所有的逻辑 包括集成的debug功能 Warm
  • Netty 全网最详细的教程! 没有之一!

    Netty 入门 文章目录 Netty 入门 入门案例 1 服务器端代码 2 客户端代码 3 运行流程 组件解释 使用组件 EventLoop 创建一个EventLoopServer 创建一个Client 细分 EventLoopGroup