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. 【DP-动态代理】JDK&Cglib

    需求:增强未知方法的代码 简单方案:继承或者聚合 继承,调用方法前后加增强逻辑 聚合 - 静态代理 持有被代理类对象 或者接口 可通过嵌套实现代理的组合 和 装饰器模式很像 高级方案 代理所有的类,不 ...

  2. Python 简明教程 --- 15,Python 函数

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 测试只能证明程序有错误,而不能证明程序没有错误. -- Edsger Dijkstra 目录 本节我 ...

  3. 【原】二进制部署 k8s 1.18.3

    二进制部署 k8s 1.18.3 1.相关前置信息 1.1 版本信息 kube_version: v1.18.3 etcd_version: v3.4.9 flannel: v0.12.0 cored ...

  4. centos 7 增加永久静态路由

    1 在 /etc/sysconfig/network-scripts/ 目录下添加route-eth3,eth3为实际网卡名称. [root@compute1 ~]# cat /etc/sysconf ...

  5. python字典套字典

    定义字典 familyinfo = { "family name":"Python", "family structure":[ {&quo ...

  6. Python实用笔记 (19)面向对象编程——访问限制

    在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的na ...

  7. P5676 [GZOI2017]小z玩游戏【Tarjan】

    小z玩游戏 Tarjan算是板子题吧,但是要稍微做一些修改,建边需要多考虑,建立"虚点". 题目描述 小 z 很无聊. 小 z 要玩游戏. 小 z 有\(N\)个新游戏,第\(i\ ...

  8. 微信解密encryptedDataStr获取用户信息

    A:<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">& ...

  9. ReadWriteLock锁的应用

    对于 Lock 锁来说,如果要实现 "一写多读" 的并发状态(即允许同时读,不允许同时写),需要对 "写操作" 加锁,对 "读操作" 不作要 ...

  10. 数据可视化之powerBI技巧(七)从Excel到PowerBI,生成笛卡尔积的几种方式

    假如分别有100个不重复的姓和名,把每个姓和名进行组合匹配,就可以得到一万个不重复的姓名组合,这种完全匹配的方式就是生成一个姓名的笛卡尔积. 下面就来看看生成笛卡尔积的几种方式,为了展现的方便,以5个 ...