diff --git "a/assets/\346\211\271\346\263\250 2020-07-07 105759.png" "b/assets/\346\211\271\346\263\250 2020-07-07 105759.png" new file mode 100644 index 0000000000..b300e97cb4 Binary files /dev/null and "b/assets/\346\211\271\346\263\250 2020-07-07 105759.png" differ diff --git "a/assets/\346\211\271\346\263\250 2020-07-07 110658.png" "b/assets/\346\211\271\346\263\250 2020-07-07 110658.png" new file mode 100644 index 0000000000..788ee1593d Binary files /dev/null and "b/assets/\346\211\271\346\263\250 2020-07-07 110658.png" differ diff --git "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md" "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md" index 24642bfcb9..d4a01c65b5 100644 --- "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md" +++ "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md" @@ -38,10 +38,6 @@ ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数 Channeloption.SO_KEEPALIVE参数对应于套接字选项中的SO_KEEPALIVE,该参数用于设置TCP连接,当设置该选项以后,连接会测试链接的状态,这个选项用于可能长时间没有数据交流的连接。当设置该选项以后,如果在两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文 -### Unpooled类 - -操作缓冲区的工具类 - ## 处理流式传输 数据通过网络传输,最终会缓存在一个字节数组里 diff --git "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md" "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md" index 074cb40b3c..98fe7e76c6 100644 --- "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md" +++ "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md" @@ -251,4 +251,231 @@ Channel 是线程安全的

Embedded

- \ No newline at end of file + + +## ByteBuf + +数据容器 + +- 可以进行扩展 +- 零拷贝 +- 容量按需增长 +- 读写切换不需要调用flip +- 读写使用不同索引 +- 方法链式调用 +- 引用计数 +- 池化 + +![批注 2020-07-07 105759](/assets/批注%202020-07-07%20105759.png) + +### 使用模式 + +- 堆缓冲区 + +ByteBuf将数据存储在JVM的堆空间中 + +```java +ByteBuf heapBuf = ...; +if (heapBuf.hasArray()) { ← -- 检查ByteBuf 是否有一个支撑数组 +  byte[] array = heapBuf.array(); ← -- 如果有,则获取对该数组的引用  +  int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); ← -- 计算第一个字节的偏移量。 +  int length = heapBuf.readableBytes();  ← -- 获得可读字节数 +  handleArray(array, offset, length);  ← -- 使用数组、偏移量和长度作为参数调用你的方法 +} +``` + +- 直接缓冲区 + +这种模式下的ByteBuf支持通过本地调用分配内存 + +所以直接缓冲区的数据在堆外,不会被GC处理 + +```java +ByteBuf directBuf = ...; +if (!directBuf.hasArray()) { ← -- 检查ByteBuf 是否由数组支撑。如果不是,则这是一个直接缓冲区 +  int length = directBuf.readableBytes(); ← -- 获取可读字节数 +  byte[] array = new byte[length];  ← -- 分配一个新的数组来保存具有该长度的字节数据   +  directBuf.getBytes(directBuf.readerIndex(), array); ← -- 将字节复制到该数组 +  handleArray(array, 0, length); ← -- 使用数组、偏移量和长度作为参数调用你的方法 +} +``` + +- 复合缓冲区 + +这种模式下允许多个ByteBuf聚合起来,提供一个ByteBuf整体视图来进行操作 + +### 字节级操作 + +- 随机访问 + +```java +ByteBuf buffer = ...; +for (int i = 0; i < buffer.capacity(); i++) { +  byte b = buffer.getByte(i); +  System.out.println((char)b); +} +``` + +不会改变索引的值 + +- 顺序访问 + +![批注 2020-07-07 110658](/assets/批注%202020-07-07%20110658.png) + +调用discardReadBytes()可以回收可丢弃字节的空间 + +读取所有数据 + +```java +ByteBuf buffer = ...; +while (buffer.isReadable()) { +  System.out.println(buffer.readByte()); +} +``` + +写入数据 + +```java +ByteBuf buffer = ...; +while (buffer.writableBytes() >= 4) { +  buffer.writeInt(random.nextInt()); +} +``` + +- 索引管理 + - readerIndex(int):设置读索引位置 + - writerIndex(int): 设置写索引位置 + - clear():将读索引写索引重置为0 + +- 查找 + +```java +// 查找回车符(\r) +ByteBuf buffer = ...; +int index = buffer.forEachByte(ByteBufProcessor.FIND_CR); +``` + +- 派生缓冲区 + + - duplicate() + - slice() + - slice(int, int) + - Unpooled.unmodifiableBuffer(…) + - order(ByteOrder) + - readSlice(int) + - copy() + +这些方法都会返回一个新的ByteBuf实例 + +- 读/写 + - get和set操作,从给定的索引开始,并且保持索引不变; + - read和write操作,从给定的索引开始,并且会根据已经访问过的字节数对索引进行调整。 +- 其他操作 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名  称

描  述

isReadable()

如果至少有一个字节可供读取,则返回true

isWritable()

如果至少有一个字节可被写入,则返回true

readableBytes()

返回可被读取的字节数

writableBytes()

返回可被写入的字节数

capacity()

返回ByteBuf可容纳的字节数。在此之后,它会尝试再次扩展直 到达到maxCapacity()

maxCapacity()

返回ByteBuf可以容纳的最大字节数

hasArray()

如果ByteBuf由一个字节数组支撑,则返回true

array()

如果 ByteBuf由一个字节数组支撑则返回该数组;否则,它将抛出一个UnsupportedOperationException异常

+ +### ByteBufHolder + +- 支持缓冲区池化 + - 从池中复用ByteBuf + + + + + + + + + + + + + + + + + + + + + + +

名  称

描  述

content()

返回由这个ByteBufHolder所持有的ByteBuf

copy()

返回这个ByteBufHolder的一个深拷贝,包括一个其所包含的ByteBuf的非共享副本

duplicate()

返回这个ByteBufHolder的一个浅拷贝,包括一个其所包含的ByteBuf的共享副本

+ +### ByteBuf分配 + +**ByteBufAllocator** + +- 池化 +- buffer 返回基于对或者直接缓存存储 +- headBuffer 返回基于堆内存 +- directBuffer 返回基于直接内存 +- compositeBuffer +- ioBuffer 返回套接字的IO操作buffer + +实现: + +- PooledByteBufAllocator + - 池化 +- UnpooledByteBufAllocator + - 每次调用都会返回一个新实例 + +**Unpooled缓冲区** + +提供了一些静态方法来创建ByteBuf实例 + +**ByteBufUtils** + +- hexdump 以16进制打印缓冲区 +- equals 比较两个ByteBuf + +### 引用计数 + +ByteBuf 与 ByteBufHolder 都实现了引用计数 + +```java +boolean released = buffer.release(); ← -- 减少到该对象的活动引用。当减少到0 时,该对象被释放,并且该方法返回true +``` + +访问一个引用计数被释放的对象 会抛出异常 \ No newline at end of file