[netty]netty学习笔记总结
Netty学习笔记
一ByteBuf
1 非池化内存:
UnpooledByteBufAllocator.DEFAULT.heapBuffer(8192);
2 池化内存:
1 //-----常规使用 2 3 //新建池化内存数据 4 5 ByteBuf buf = PooledByteBufAllocator.DEFAULT.heapBuffer(16); 6 7 //写入数据 8 9 buf.writeByte(1); 10 11 //将读过的字符串进行丢弃 12 13 buf.discardReadBytes(); 14 15 //打印读和写的小标 16 17 System.out.println(buf.readerIndex()+"|"+buf.writerIndex()); 18 19 //打印剩余可读写情况长度 20 21 System.out.println(buf.readableBytes()+"|"+buf.writableBytes()); 22 23 //通过指定的下标设置值 24 25 newBuf.setByte(0,9); 26 27 //增加引用计数器 28 29 buf.retain(); 30 31 //打印引用计数器数量 32 33 System.out.println(buf.refCnt()); 34 35 36 37 //------复制索引 38 39 //复制一份索引出来,但是指向的内存地址是相同的; 40 41 //retainedDuplicate会使计数器加1 42 43 ByteBuf newBuf = buf.duplicate(); 44 45 newBuf.writeByte(6); 46 47 48 49 //------指定选取部分空间 50 51 //slice(),slice(int index, int length) 52 53 //指定选取的下标位置和长度 54 55 ByteBuf newSliceBuf = buf.slice(buf.readerIndex(), buf.readableBytes()); 56 57 //readSlice(int length)和readRetainedSlice(int length) 58 59 //返回部分空间,彼此共享底层缓冲区,会增加原缓冲区的readerIndex 60 61 ByteBuf readBuf = buf.readSlice(buf.readerIndex()); 62 63 64 65 //释放 66 67 buf.release();
二 Handler
1 ChannelInboundHandlerAdapter 处理入站数据
继承该类并重写channelRead方法
public void channelRead(ChannelHandlerContext ctx, Object msg)
2 ChannelOutboundHandlerAdapter处理出站数据
继承该类并重写 write 方法
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
3 ChannelDuplexHandler处理出站和入站数据
该类同时具有channelRead 和 write 的能力
三 编解码器
1 字符编解码器 StringEncoder StringDecoder
pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));
2 分隔符 \r\n解码器 LineBasedFrameDecoder
ch.pipeline().addLast("lineDecoder",new LineBasedFrameDecoder(1024));
3 自定义分隔符 DelimiterBasedFrameDecoder
ch.pipeline().addLast("DelimiterBasedFrameDecoder",new DelimiterBasedFrameDecoder(
Integer.MAX_VALUE, Unpooled.wrappedBuffer("||".getBytes()))
);
4 定长解码器 FixedLengthFrameDecoder
ch.pipeline().addLast("fixedDecoder",new FixedLengthFrameDecoder(3));
5 LengthFieldBasedFrameDecoder
/*
lengthFieldOffset
起始位置,Length的偏移量,可以作为头部的长度
lengthFieldLength
有效的数据体长度
lengthAdjustment
偏移校验,满足公式:发送的字节数组
bytes.length - lengthFieldLength =
bytes[lengthFieldOffset, lengthFieldOffset+lengthFieldLength] + lengthFieldOffset +
lengthAdjustment
initialBytesToStrip
将数据传递给下一个channel时去除包含描述长度的信息
*/
例:
ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
String str = "Hello,World";
1) 0,2,0,0
编码:
//长度描述占用2个字节,使用writeShort
buffer.writeShort(str.getBytes().length);
buffer.writeBytes(str.getBytes());
//转为16进制,后面例子略掉该项
ByteBufUtil.hexDump(buffer);
解码:
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,2,0,0)
2) 0,2,-2,0
编码:
//长度描述占2两个字节,描述的长度包含长度描述本身长度
buffer.writeShort(str.getBytes().length+2);
buffer.writeBytes(str.getBytes());
解码:
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,2,-2,0)
3) 2,3,0,0
编码:
//自定义头信息
buffer.writeBytes("AB".getBytes());
//长度描述占用3个字节,使用writeMedium
buffer.writeMedium(str.getBytes().length);
buffer.writeBytes(str.getBytes());
解码:
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,2,3,0,0)
4) 0,3,2,0
编码:
//长度描述占用3个字节
buffer.writeMedium(str.getBytes().length);
//HDR附加信息
buffer.writeBytes("AB".getBytes());
buffer.writeBytes(str.getBytes());
解码:
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,3,2,0)
5) 1,2,1,3
编码:
//自定义头信息
buffer.writeBytes("A".getBytes());
//长度描述占用2个字节
buffer.writeShort(str.getBytes().length);
//HDR附加信息
buffer.writeBytes("B".getBytes());
buffer.writeBytes(str.getBytes());
解码:
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,1,2,1,3)
6) 1,2,-3,3
编码:
//自定义头信息
buffer.writeBytes("A".getBytes());
//长度描述占用2个字节
buffer.writeShort(str.getBytes().length+4);
//HDR附加信息
buffer.writeBytes("B".getBytes());
buffer.writeBytes(str.getBytes());
解码:
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,1,2,-3,3)