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学习笔记(三) 自定义编码器
编写一个网络应用程序需要实现某种编解码器,编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码, ...
随机推荐
- 【解读】Http协议
一.HTTP简介 1.HTTP协议,即超文本传输协议(Hypertext transfer protocol).是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相 ...
- elasticSearch中集群状态的guan'l
es中集群出现上面的问题一般是磁盘空间不够引起的,就是node节点所在的磁盘空间不足引起的 es整个集群放在c盘,都快满了 说明es的磁盘已经快被使用完了,我们可以临时更新下磁盘空间大小 修改 ES分 ...
- elasticSearch插件metricbeat收集nginx的度量指标
ngx_http_stub_status_module模块是Nginx中用来统计Nginx服务所接收和处理的请求数量,只要在编译安装Nginx的时候加上参数--with-http_stub_statu ...
- 在树莓派上读取DHT11温湿度传感器-python代码实现及常见问题(全面简单易懂)
最近由于自己的课题需要,想要用在树莓派上使用DHT11温湿度传感器来读取空气中温湿度,遇到了几个问题,解决之后也对之前的知识进行了回顾,总结,特整理如下,希望能给也在学习树莓派的小伙伴们带来一些帮助. ...
- Package Control:There are no packages available for installation
百度推荐的sublime3,里面好多全家桶,注意安装. 我的问题报错是:Package Control:There are no packages available for installation ...
- sublime清空控制台
解决方法 – 只需运行print('\n'*100)打印100个换行符,您将无法看到任何以前的输出,除非你向上滚动一些距离.
- 部署JUnit
JUnit的简介和使用:http://blog.csdn.net/luanlouis/article/details/37562165 jar包下载地址:http://www.java2s.com/C ...
- C#由转换二进制所引起的思考,了解下?
前言 最近遇到很有意思转换二进制的问题,有部分童鞋俨然已了解,可能也有一部分童鞋没碰到过也就不知情,这里我们来深入学习下转换二进制所带来的问题. 二进制转换问题 假设现在我们有一个int类型的数据,它 ...
- spark | 手把手教你用spark进行数据预处理
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是spark专题的第七篇文章,我们一起看看spark的数据分析和处理. 过滤去重 在机器学习和数据分析当中,对于数据的了解和熟悉都是最基 ...
- 第一章 java基本多线程技能
第一章 java多线程技能 1 线程:进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理顺序时发生的活动:是程序在一个数据集合上运行的过程,他是系统进行资源分配和调度的一个独立单位. ...