Netty中读写以ByteBuf为载体进行交互

ByteBuf的结构

  1. ByteBuf以readerIndex和writerIndex划分为三块区域,废弃字节,可读字节,可写字节。每次从ByteBuf读取一个字节时readerIndex+1,写入一个字节时writerIndex+1。
  2. 废弃字节,这部分的数据是无效的,范围为0~readerIndex-1
  3. 可读字节,从ByteBuf读取的数据都来自这块区域,范围为readerIndex~writerIndex-1,当readerIndex与writerIndex相等时不可读。
  4. 可写字节,写入的数据存放的区域,范围为writerIndex~capacity,当capacity与writerIndex相等时不可写,但是ByteBuf还有一个maxCapacity,容量不足时可以进来扩容,当容量超过maxCapacity时会报错。

读取

	ByteBuf byteBuf = Unpooled.copiedBuffer("hello world".getBytes());
//判断是否有可读的字节
System.out.println(byteBuf.isReadable());
//返回可读字节数
System.out.println(byteBuf.readableBytes());
//返回当前的读指针
System.out.println(byteBuf.readerIndex());
while (byteBuf.isReadable()) {
//以read开头的方法都是读取方法,readInt、readBoolean等
byteBuf.readByte();
}
System.out.println(byteBuf.readerIndex());
//设置读指针
byteBuf.readerIndex(0);
//将当前可读数据都读取到byte[]中
byteBuf.readBytes(new byte[byteBuf.readableBytes()]);

写入

	//分配capacity为9,maxCapacity为12的byteBuf
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(9, 12);
//返回可写字节数
System.out.println(byteBuf.writableBytes());
//判断是否可写
System.out.println(byteBuf.isWritable());
//以write开头的都是写入方法
byteBuf.writeByte(1);
byteBuf.writeInt(1);
byteBuf.writeBytes(new byte[]{1,2,3,4});
//获取写指针
System.out.println(byteBuf.writerIndex());
//这时writerIndex==capacity
System.out.println(byteBuf.writableBytes());
System.out.println(byteBuf.isWritable());
//再写入将扩容
byteBuf.writeByte(1);
System.out.println(byteBuf.isWritable());
System.out.println(byteBuf.writableBytes());
//扩容后仍然不足存放将报错
//byteBuf.writeInt(1);
//设置写指针
byteBuf.writerIndex(0);
System.out.println(byteBuf.isWritable());
System.out.println(byteBuf.writableBytes());
byteBuf.writeInt(1);

引用计数

release() 与 retain()
  1. netty使用的是堆外内存,不被jvm管理,所以需要我们手动释放。
  2. netty使用引用计数管理ByteBuf,如果没有地方引用一个ByteBuf,将直接回收底层内存。
  3. 一个ByteBuf被创建时引用为1,retain()将使引用+1,release()使引用-1,为0时将被回收。
  4. 一般遵循谁retain()(包括创建)谁release()

slice()、duplicate()、copy()

  1. slice()截取可读字节区域返回,新的ByteBuf的maxCapacity为旧的readableBytes(),但底层内存和引用共用
  2. duplicate()为ByteBuf的浅拷贝,读写指针与旧的无关,但底层内存和引用共用
  3. copy()为深拷贝,读写指针、引用和内存都无关
  4. slice()和duplicate()不会增加引用计数,而retainedSlice() 与 retainedDuplicate()会增加计数。

参考资料

Netty实战

Netty 入门与实战:仿写微信 IM 即时通讯系统

Netty 学习笔记(2) ------ 数据传输载体ByteBuf的更多相关文章

  1. Netty 学习笔记(1)通信原理

    前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始.   Netty 的通信原理 Netty 底层 ...

  2. Netty学习笔记(二) 实现服务端和客户端

    在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...

  3. Netty学习笔记-入门版

    目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...

  4. Netty学习笔记(二)——netty组件及其用法

    1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...

  5. Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例

    在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...

  6. Netty学习笔记(一)

    学习圣思园Netty笔记,个人理解 2.netty宏观理解-本节内容: 1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式. 2.net ...

  7. Netty学习笔记

    一些类与方法说明 1)ByteBuf ByteBuf的API说明: Creation of a buffer It is recommended to create a new buffer usin ...

  8. Netty学习笔记(一):接收nodejs模拟表单上传的文件

    好久不写博客了,也好久不写代码了,这两天临时遇上一个事情,觉得不难,加上觉得手有些生,就动手做了一下,结果遇上了不少坑,有新坑,有老坑,痛苦无比,现在总算差不多了,赶紧记录下来,希望以后不再重复这种痛 ...

  9. Netty学习笔记(三) 自定义编码器

    编写一个网络应用程序需要实现某种编解码器,编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码, ...

随机推荐

  1. Struts2 自定义拦截器时Action无法接收到参数

    问题:自定义拦截器,没有添加defaultStack导致Action无法接受到参数 解决办法: 方法一,添加defaultStack,然后在Action中引用 自定义的stack,其实defaultS ...

  2. Exception in thread "main" java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D

    问题原因是Hive里面配置的相对路径没有找到,我们可以直接在文件里面修改为绝对路径. 1.在hive下面窗口temp文件夹 cd /opt/hive mkdir temp cd temp 2.查看te ...

  3. 写给程序员的机器学习入门 (七) - 双向递归模型 (BRNN) - 根据上下文补全单词

    这一篇将会介绍什么是双向递归模型和如何使用双向递归模型实现根据上下文补全句子中的单词. 双向递归模型 到这里为止我们看到的例子都是按原有顺序把输入传给递归模型的,例如传递第一天股价会返回根据第一天股价 ...

  4. 洛谷 P1313 【计算系数】

    这道题只要肯动手还是挺水的 进入正题 我们先枚举几个找找规律(这里先省略x,y): k = 0 :\(1\) k = 1 : \(a\) \(b\) k = 2 : \(a^{2}\) \(2ab\) ...

  5. 七.数据分页原理,paginator与page对象

    1.分页: Paginator对象 Page对象 2.Paginator: class Paginator(object_list, per_page, orphans=0, allow_empty_ ...

  6. 2020年全新web前端学习路线图,学完就业20K!

    第一阶段:HTML5+css 配套学习视频: 前端小白零基础入门HTML5+CSS3 第二阶段:移动web网页开发 移动web进阶教程 第三阶段:JavaScript网页编程 前端与移动开发基础入门到 ...

  7. css如何让文字不换行显示?

    在CSS中,可以通过white-space属性来实现文字不换行显示:只要将white-space属性的值为nowrap就可强制文字不换行. white-space属性指定元素内的空白怎样处理.它有以下 ...

  8. Django---进阶12

    目录 Auth模块 方法总结 如何扩展auth_user表 项目开发流程 表设计 作业 Auth模块 """ 其实我们在创建好一个django项目之后直接执行数据库迁移命 ...

  9. 震惊!慎老师怒吃pks并大呼:一口就吃完了!

    慎老师吃pks是怎么回事呢?慎老师相信大家都很熟悉,但是慎老师吃pks是怎么回事呢,下面就让小编带大家一起了解吧. 慎老师吃pks,其实就是慎老师把花花蛤吃了,大家可能会很惊讶慎老师怎么会吃花花蛤呢? ...

  10. 如何使用CSS3 调节 tab的高度

    包含大量代码的网页(比如文档或教程)在样式上面对着无法回避的挑战.我们通常使用 <pre> 和 <code> 元素来显示代码,它们具有浏览器所赋予的默认样式.这些默认样式往往是 ...