Netty (3)-ByteBuf、池、直接内存、16进制

2023-11-04

传统IO在收发数据时,会阻塞当前线程,一边接收数据,一边对数据进行处理,处理完一段数据再继续接收下一段,再处理。而NIO会一次性将接收的所有数据,放入内存,处理数据时只需要读取内存,而IO线程被完全释放,这就是非阻塞。而被放入内存的数据在 netty中的表现形式就是本篇要讲的ByteBuf

接收数据

继续延用修改第1篇的代码,以下就是一次性接收数据放入内存(ByteBuf),并且打印出来的过程

	public void channelRead(ChannelHandlerContext ctx, Object msg) { 
		ByteBuf in = (ByteBuf) msg;    //把收到的数据msg转换成ByteBuf
		System.out.println(in.toString(CharsetUtil.UTF_8));    //以UTF-8格式转换成字符串

发送数据

如果要发出数据,也要先将数据放入内存,即转换成ByteBuf。再一次性的从内存把数据发出去,避免写的过程阻塞IO

	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		ByteBuf out = Unpooled.buffer();    //创建一个ByteBuf 
		out.writeBytes("hello".getBytes());    //将字符串写入ByteBuf 
		ctx.writeAndFlush(out);     //发出ByteBuf 

逐字读取

在一些场景中,需要对ByteBuf进行逐个字节的处理,比如:接收的数据中第1个字符代表类型,第2个字符代表状态等,根据每个字节的值,都需要做各种不同的处理

	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		ByteBuf in = (ByteBuf) msg;    
		while(in.isReadable()){    //是否有可读数据
			byte b = in.readByte();    //读取一个字节
			System.out.println((char)b);    //打印出来
		}

关于isReadable())方法:ByteBuf中的数据存放在一个数组中,读取数据时从头部开始,并记录读取位置。每读取一次,位置会向后偏移,当读取到尾部,没有更多可读数据时,这个方法结果就会为否。

上面发送数据代码中有个Unpooled,即非池,每次需要重新创建ByteBuf,用完后销毁。使用池可以重复利用,以提高性能,类似连接池。,PooledByteBufAllocator可用于实现池的操作,如下

	PooledByteBufAllocator pool = PooledByteBufAllocator.DEFAULT;
	
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		ByteBuf out = pool.buffer();
		out.writeBytes("hello".getBytes());	
		ctx.writeAndFlush(out);

堆内存和直接内存

开头说过,收发的数据存入在内存中,即ByteBuf。而存入不同的内存,效果也不一样。

  • 堆内存:由JAVA虚拟机创建并管理回收的一部分内存,性能较高。
  • 直接内存:是JVM以外的系统内存,显然性能会比堆内存低。

但是,在对外收发数据时,不能直接使用JVM中的堆内存,需要用直接内存。此时,netty会自动将堆内存中的数据复制到直接内存,再进行收发。如果使用直接内存,则可省略了这一步骤。所以

  • 进行大量后台业务处理时,使用堆内存。
  • 收发数据时,使用直接内存。

netty默认情况下,使用的直接内存。也可以自己指定

		pool.heapBuffer();		//堆内存
		pool.directBuffer();	//直接内存

16进制

  • 前面代码中1个字节通过ASCII值,只能存储一个字符的内容,可表达的指令意义有限,如数字指令只能表达0-9。而同样的空间用16进制来存储的话,一个字符可以存储2个16进制,16*16-256,可表达数字指令0-255。
  • 计算机原始语言就是二进制,16进制数其实就是由4个二进制数组成。对计算机而说,如果二进制算普通话,16进制可以算方言,是可以听的懂的语言。而字符则属于外语,需要翻译,所以计算机更乐于处理数字指令。

因此,服务器与机器之间,普遍采用16进制的数字指令进行通讯。除非有人为参与的语言通讯,比如聊天,才必须要采用字符串进行通讯。接收16进制代码如下

	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		ByteBuf in = (ByteBuf) msg;
		System.out.println(ByteBufUtil.hexDump(in));    //转换16进制 

也可以逐个读取字节

	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		ByteBuf in = (ByteBuf) msg;
		while(in.isReadable()){ 
			int b = in.readByte()& 0xFF ;    //读取1个字节转成10进制int表示
			System.out.println(Integer.toHexString(b));    //再转成2个16进制字符串
		}

发出16进制,如下。前面说过,一个byte刚好存储2个16进制,以下发出了2个byte,即4个16进制数:1122

		ByteBuf out = pool.buffer();
		out.writeByte(0x11);    //0x前缀的16进制
		out.writeByte(Integer.parseInt("22", 16));    //将字符串转换成16进制
		ctx.writeAndFlush(out);

多字节读写

前面的代码中,writeByte和readByte都是单字节读写,也可以是多字节

		ByteBuf out = pool.buffer();
		out.writeByte(0x11);		//1个字节
		out.writeShort(0x2222);		//2个字节
		out.writeMedium(0x333333);	//3个字节
		out.writeInt(0x44444444);	//4个字节

以上是写方法,读取方法也是一样,write换成read

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

Netty (3)-ByteBuf、池、直接内存、16进制 的相关文章

  • 如何使用netty在单独的线程池中执行业务逻辑处理程序

    我有一个需要执行一些业务逻辑的处理程序 我希望它在单独的线程池中执行 以免阻塞 io 事件循环 我已将 DefaultEventExecutorGroup 添加到管道中 如中指定的http netty io 4 0 api io netty
  • Java Netty负载测试问题

    我使用文本协议编写了 接受连接和轰炸消息 100 字节 的服务器 并且我的实现能够使用第 3 方客户端发送大约 400K 秒的环回消息 我为这项任务选择了 Netty SUSE 11 RealTime JRockit RTS 但是当我开始基
  • netty-daxin-4(http&websocket)

    文章目录 http 服务端 NettyHttpServer HelloWorldServerHandler 客户端 ApiPost
  • netty源码:(28)ChannelPromise

    ChannelPromise是ChannelFuture的子接口 它是可写入的 其父接口Promise定义如下 ChannelPromise有个默认的实现类 DefaultChannelPromise 它的setSuccess方法用来调用所
  • 如何管理标识您的协议的前缀字节序列

    这与我有关统一设置的问题有关 具有持久通道的端口统一 https stackoverflow com questions 18445861 port unification with persistent channel 我正在尝试发送一个
  • 如何在 Netty 通道处理程序中安全地执行阻塞操作?

    我正在构建一个基于 Netty 的小型应用程序 该应用程序通过套接字连接 即 telnet ssh 执行 I O 操作 我正在使用 Netty 启动我的套接字服务器ServerBootstrap类 给出 类型的事件循环NioEventLoo
  • Java NIO 窗口实现

    在使用 NIO 2 AIO 功能进行项目时 我查看了 旧的 NIO 选择器实现 发现在 Windows 上使用了默认的选择函数 由于内部实现不良 该函数在 Windows 上根本无法扩展 大家都知道 在 Windows 上 IOCP 是唯一
  • Netty的并发编码

    编码器的encode方法会并发执行吗 我观察到编码方法可能是由不同线程并发的 管道定义为 Channels pipeline idleHandler new AmfDecoder
  • 使用netty高速发送消息时出现OOM异常

    我用netty编写了一个客户端 以便以高速率发送消息 通过 jConsole 我看到 老一代 正在增加 最后它抛出 java lang OutOfMemoryError 超出 GC 开销限制 是否有一些方法或配置可以避免此异常 以下是我的测
  • Netty 支持哪个 TLS 版本? TLS 1.0、1.1 还是 1.2?

    Netty 支持哪个 TLS 版本 TLS 1 0 1 1 还是 1 2 我在看http netty io 5 0 xref io netty handler ssl SslHandler html http netty io 5 0 xr
  • Netty异步写入响应和大小未知的大数据

    我开发了一个netty http服务器 但是当我在方法ChannelInboundHandlerAdapter channelRead0中写入响应时 我的响应结果来自另一台服务器 并且结果的大小未知 因此它的http响应标头可能具有内容长度
  • Netty:关闭通道时出现 ClosedChannelException

    为什么当我尝试关闭通道时 会抛出 ChannelClosedException 使用 Channel close 关闭 异常的堆栈跟踪 java nio channels ClosedChannelException at org jbos
  • 使用 TLS 1.2 将客户端连接到 TCP 服务器

    我尝试将设备连接到 Net 4 5 2 服务器 但没有成功 它是设备打开的 TCP 连接 使用 TLS 1 2 在服务器端 我有一个 TCP 服务器的标准 Net 实现 SslStream包裹着DotNetty https github c
  • 出站 ChannelHandler 的捕获所有异常处理

    在 Netty 中 您有入站和出站处理程序的概念 只需在管道的末尾 尾部 添加一个通道处理程序并实现一个捕获所有入站异常处理程序即可实现exceptionCaught覆盖 如果未沿途处理 沿入站管道发生的异常将沿着处理程序传播 直到遇到最后
  • Netty的ChannelLocal的使用

    Netty 的 JavaDocs 解释 ChannelLocal 与 ThreadLocal 类似 但是我对它的用法有一些疑问 ThreadLocal 是一个静态类 具有访问特定于实例的对象的静态方法 ChannelLocal 不是静态的
  • 如何在Netty中使用多个ServerBootstrap对象

    我正在尝试使用 Netty 4 0 24 在一个应用程序 一个主要方法 中创建多个服务器 多个 ServerBootstrap 我看到了这个问题 答案 但它留下了许多未解答的问题 Netty 4 0多端口 每个端口有不同的协议 https
  • Spring WebClient:SSLEngine 已关闭

    我们使用 Spring boot 版本 2 3 1 也使用 WebClient 我的网络客户端配置 private val client WebClient init val sslCtx SslContextBuilder forClie
  • 为什么我们真的需要多个 Netty boss 线程?

    我真的很困惑老板组的线程数量 我无法弄清楚我们需要多个老板线程的场景 在Boss 组是否需要多个线程 https stackoverflow com questions 22280916 do we need more than a sin
  • 如何使用 Netty 发送对象?

    如何通过Netty从服务器端发送bean并在客户端接收该bean 当我发送简单的整数消息 inputstream 时 它工作成功 但我需要发送 bean 如果您在客户端和服务器端使用 Netty 那么您可以使用 Netty对象解码器 htt
  • HashedWheelTimer 与 ScheduledThreadPoolExecutor 相比以获得更高的性能

    我正在考虑如果您需要在一台机器上的 jvm 内尽可能快地调度大量 非阻塞 任务 则应使用哪种计时器实现 我学过ScheduledThreadPoolExecutor and HashedWheelTimer来源 轮计时器一般文档 和以下是基

随机推荐

  • windows下免费本地部署类ChatGpt的国产ChatGLM-6B

    ChatGLM 6B 是一个开源的 支持中英双语的对话语言模型 基于 General Language Model GLM 架构 具有 62 亿参数 结合模型量化技术 用户可以在消费级的显卡上进行本地部署 INT4 量化级别下最低只需 6G
  • 万字长文,SpringSecurity

    思维导图如下 RBAC权限分析 RBAC 全称为基于角色的权限控制 本段将会从什么是RBAC 模型分类 什么是权限 用户组的使用 实例分析等几个方面阐述RBAC 思维导图 绘制思维导图如下 什么是RBAC RBAC 全称为用户角色权限控制
  • javascript算法之数组反转浅谈

    本文主要介绍了javascript算法之数组反转 文章围绕主题展开详细的内容介绍 具有一定的参考价值 需要的小伙伴可以参考一下 1 数组反转 1 1 leecode题目 旋转数组 给你一个数组 将数组中的元素向右轮转 k 个位置 其中 k
  • Servlet是不是线程安全的?

    首先在servlet中的方法 三个重要方法 1 init 进行资源的加载 2 service 处理请求 根据请求方式 调用doGet或者doPost 3 destroy 进行资源的释放 servlet是单实例的 假如在处理请求时候 多线程访
  • AcWing 104. 货仓选址

    题目 在一条数轴上有 N 家商店 它们的坐标分别为 A1 AN 现在需要在数轴上建立一家货仓 每天清晨 从货仓到每家商店都要运送一车商品 为了提高效率 求把货仓建在何处 可以使得货仓到每家商店的距离之和最小 输入格式 第一行输入整数N 第二
  • windows下访问linux下的文件,【IT之家学院】如何从Win10访问Linux子系统中的文件 - IT之家...

    在19H1 目前处于Insider Preview阶段 预计4月份正式推送 中 微软为适用于Linux的Windows子系统带来了一项有趣的功能 这项功能允许用户从Windows 10访问Linux子系统中的文件 今天的这期教程 我们来讨论
  • AppScan 漏扫工具-保姆及配置使用说明

    本文章仅供学习使用 严禁在未经网站管理员的允许的条件下扫描任何网站 工具的滥用违反国家安全法后果自负 申明 本文实验环境在内网中进行 网站为自己服务器所搭建的sqli labs DVWA master测试网站 1 AppScan安装和基础配
  • 请分别创建出listA、listB、listC,完成以下各题 (1)将listC中的内容添加到listB中: (2)输出listA与listB的交集listD; (3)输出listA与listB的并集...

    答 1 将listC中的内容添加到listB中 将listC中的每一项元素都添加到listB尾部 2 输出listA与listB的交集listD 定义一个空listD 遍历listA中的每个元素 如果listB中有相同的元素 则将该元素加入
  • 爬虫碰到状态码412的解决办法

    爬虫碰到状态码412 近期在使用python的requests库爬取网页时 碰到返回状态码为412的情况 状态码412含义为 Precondition Failed 服务器在验证在请求的头字段中给出先决条件时 没能满足其中的一个或多个 这个
  • Arthas 使用实践

    文章目录 1 Arthas 2 学习总结 2 1 所有环境都在线上 学习时不用自己搭环境 2 2 官方文档 2 3 相关参考博文 2 4 idea arthas 插件 3 各种捣腾 3 1 Arthas 下载使用 3 2 支持管道操作 3
  • 物联网智能病床项目

    目录 第一部分 系统架构 第二部分 MCU工作过程 第三部分 嵌入式操作系统 第一部分 系统架构 总体采用设备端 MCU 医用传感器 通信模组 WiFi 蓝牙 4G 通信端 MQTT协议 应用层服务器组成构建一整套物联网系统 第二部分 MC
  • pytest框架之fixture测试夹具详解

    一 fixture的优势 pytest框架的fixture测试夹具就相当于unittest框架的setup teardown 但相对之下它的功能更加强大和灵活 命名方式灵活 不限于unittest的setup teardown 可以实现数据
  • 14-1_Qt 5.9 C++开发指南_网络编程及主机信息查询_HostInfo

    Qt 网络模块提供了用于编写 TCP IP 客户端和服务器端程序的各种类 如用于 TCP 通信的QTcpSocket 和 QTcpServer 用于 UDP 通信的 QUdpSocket 还有用于实现 HTTP FTP 等普通网络协议的高级
  • Flex4 Error #2032 Stream Error的解决方式

    最近在做一个项目 在程序发布的初期没有发现什么问题 但是有的用户反映看不到站点 并截图Error 2032错误 但是在研发中心测试没有问题 后来通过测试幸运地在一台测试机上发现了这个问题 而同时测试其他9台机器 发现都可以正常显示 而后到网
  • C语言中void*详解及应用

    void在英文中作为名词的解释为 空虚 空间 空隙 而在C语言中 void被翻译为 无类型 相应的void 为 无类型指针 void似乎只有 注释 和限制程序的作用 当然 这里的 注释 不是为我们人提供注释 而是为编译器提供一种所谓的注释
  • 开源毕业设计:基于嵌入式ARM-Linux的应用OpenCV和QT实现的人脸识别系统(源码+论文)

    毕业一载有余 把毕业设计作品分享一下 希望能帮助到有需要的同学们 资料获取 帮助 答疑 辅导 等请联系博主 请点如下链接 linux face txt zengzr share contact Gitee com 毕设课题选题参考 毕业设计
  • 在WIN10上用QT Creator写安卓APP

    操作系统 WIN 10 HOME QT 5 15 QT Creator 4 12 先讲一下踩过的坑 坑 本意用 虚拟机好复制移植 用了vm14 结果发现报错 adb fail to install 以为是QT的问题 结果不是 因为直接用指令
  • python字符串替换空格_Python去除、替换字符串空格的处理方法

    个人想到的解决方法有两种 一种是 replace old new 第一个参数是需要换掉的内容比如空格 第二个是替换成的内容 可以把字符串中的空格全部替换掉 第二种方法是像这样 str 1 data a b c str 2 list str
  • 用海伦公式求三角形周长与面积 C++

    海伦公式又译作希伦公式 海龙公式 希罗公式 海伦 秦九韶公式 它是利用三角形的三条边的边长直接求三角形面积的公式 表达式为 S p p a p b p c 其中p等于周长的一半 给出平面坐标上不在一条直线上三个点坐标 x1 y1 x2 y2
  • Netty (3)-ByteBuf、池、直接内存、16进制

    传统IO在收发数据时 会阻塞当前线程 一边接收数据 一边对数据进行处理 处理完一段数据再继续接收下一段 再处理 而NIO会一次性将接收的所有数据 放入内存 处理数据时只需要读取内存 而IO线程被完全释放 这就是非阻塞 而被放入内存的数据在