Netty 学习笔记(2) ------ 数据传输载体ByteBuf
Netty中读写以ByteBuf为载体进行交互
ByteBuf的结构
- ByteBuf以readerIndex和writerIndex划分为三块区域,废弃字节,可读字节,可写字节。每次从ByteBuf读取一个字节时readerIndex+1,写入一个字节时writerIndex+1。
- 废弃字节,这部分的数据是无效的,范围为0~readerIndex-1
- 可读字节,从ByteBuf读取的数据都来自这块区域,范围为readerIndex~writerIndex-1,当readerIndex与writerIndex相等时不可读。
- 可写字节,写入的数据存放的区域,范围为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()
- netty使用的是堆外内存,不被jvm管理,所以需要我们手动释放。
- netty使用引用计数管理ByteBuf,如果没有地方引用一个ByteBuf,将直接回收底层内存。
- 一个ByteBuf被创建时引用为1,retain()将使引用+1,release()使引用-1,为0时将被回收。
- 一般遵循谁retain()(包括创建)谁release()
slice()、duplicate()、copy()
- slice()截取可读字节区域返回,新的ByteBuf的maxCapacity为旧的readableBytes(),但底层内存和引用共用
- duplicate()为ByteBuf的浅拷贝,读写指针与旧的无关,但底层内存和引用共用
- copy()为深拷贝,读写指针、引用和内存都无关
- slice()和duplicate()不会增加引用计数,而retainedSlice() 与 retainedDuplicate()会增加计数。
参考资料
Netty实战
Netty 入门与实战:仿写微信 IM 即时通讯系统
Netty 学习笔记(2) ------ 数据传输载体ByteBuf的更多相关文章
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- Netty学习笔记-入门版
目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...
- Netty学习笔记(二)——netty组件及其用法
1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...
- Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例
在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...
- Netty学习笔记(一)
学习圣思园Netty笔记,个人理解 2.netty宏观理解-本节内容: 1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式. 2.net ...
- Netty学习笔记
一些类与方法说明 1)ByteBuf ByteBuf的API说明: Creation of a buffer It is recommended to create a new buffer usin ...
- Netty学习笔记(一):接收nodejs模拟表单上传的文件
好久不写博客了,也好久不写代码了,这两天临时遇上一个事情,觉得不难,加上觉得手有些生,就动手做了一下,结果遇上了不少坑,有新坑,有老坑,痛苦无比,现在总算差不多了,赶紧记录下来,希望以后不再重复这种痛 ...
- Netty学习笔记(三) 自定义编码器
编写一个网络应用程序需要实现某种编解码器,编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码, ...
随机推荐
- Redis 的基本数据类型 和 基础应用场景
Redis 的基础应用场景 获取中奖用户ID,随机弹出之后集合中就不存在了[set] 存储活动中中奖的用户ID,保证同一个用户不会中奖两次[set] 存储粉丝列表,value 为粉丝的用户ID,sco ...
- 并发04--JAVA中的锁
1.Lock接口 Lock与Synchronized实现效果一致,通过获得锁.释放锁等操作来控制多个线程访问共享资源,但是Synchronized将获取锁固话,必须先获得锁,再执行,因此两者对比来说, ...
- keras 从txt加载预测数据
ImageDataGenerator.flow_from_directory()的用法已经非常多了,优点是简单方便,但数据量很大时,需要组织目录结构和copy数据,很浪费资源和时间 1. 训练时从tx ...
- html+css快速入门教程(3)
练习: 1.画盒子 2.相框 5 基础选择器 5.1 id选择器 ID选择器与类选择器的定义与引用方式类似,只是定义的符号不一样.ID通常表示唯一值,因此,ID选择器在CSS 中通常只出现一次.如果出 ...
- 深入理解JVM(③)Java的模块化
前言 JDK9引入的Java模块化系统(Java Platform Module System ,JPMS)是 对Java技术的一次重要升级,除了像之前JAR包那样充当代码的容器之外,还包括: 依赖其 ...
- 洛谷 P4047 [JSOI2010]部落划分
这道题其实就是无线通讯网的双倍经验啦,只是在输出的时候不同罢了.还是一样的\(kruskal\)算法,但是在求的时候,应该在\(now=n-k+1\)的时候结束.本来到\(n-k\)就行了的,但是由于 ...
- 七.数据分页原理,paginator与page对象
1.分页: Paginator对象 Page对象 2.Paginator: class Paginator(object_list, per_page, orphans=0, allow_empty_ ...
- 部署LNMP环境——Yum安装(113资讯网)
Yum安装优点:安装东西,方便快捷,特别是不用考虑包依赖 教程(Centos做演示,其他系统大同小异): 1.更换国内Yum源: [root@root xx ]# rm -rf /etc/yum.re ...
- iWS工作流加载顺序
1.初次加载-LoadDataFields(IsPostBack=false); 2.保存-LoadDataFields(IsPostBack=true)-ValidateDataFields-Sav ...
- C#模拟HTTP协议请求
1 前言 http协议详解参考HTTP协议. WEB常用Get和Post请求. 地址栏参数:url为www.viwofer.com?id=12&name=viwofer则id=12 ...