1.handler处理顺序
- ch.pipeline().addLast(new OutboundHandler1());
- ch.pipeline().addLast(new OutboundHandler2());
- // 注册两个InboundHandler,执行顺序为注册顺序,所以应该是InboundHandler1 InboundHandler2
- ch.pipeline().addLast(new InboundHandler1());
- ch.pipeline().addLast(new InboundHandler2());
那么收到消息时,handler执行顺序是inboundhandler1->inboundhandler2
发送消息时, 执行顺序是outboundhandler2->outboundhandler1
在使用Handler的过程中,需要注意:
1、ChannelInboundHandler之间的传递,通过调用 ctx.fireChannelRead(msg) 实现;调用ctx.write(msg) 将传递到ChannelOutboundHandler。
2、ctx.write()方法执行后,需要调用flush()方法才能令它立即执行。
3、ChannelOutboundHandler 在注册的时候需要放在最后一个ChannelInboundHandler之前,否则将无法传递到ChannelOutboundHandler。
另外也可以使用
CombinedChannelDuplexHandler<ChannelInboundHandlerAdapter, ChannelOutboundHandlerAdapter> {
那么发送接收消息都会走这个handler
2.LengthBasedFrameEncoder属性字段含义
maxFrameLength:表示帧最大长度
lengthFieldOffset :帧长度字段的起始位,从哪个字节开始是长度字段
lengthFieldLength:长度字段占多少个字节
lengthAdjustment:调节值,读完长度字段之后,还会读长度值+lengthAdjustment个字节
initialBytesToStrip:读取跳过的字节数
如果0-4字节存储帧长度,长度值表示整个帧长度(包含长度字段),那么decoder lengthAdjustment需要设为-4
假设收到一个包,长度属性值位14,那么encoder在读完长度字段后,还会读取14-4=10个字节,那么就把整个帧读完了
读完之后再根据initialBytesToStrip值,决定返回的字节数
如果initialBytesToStrip设为0, 那么decoder返回的字节数为14,readableBytes为14,包含长度字段
如果initialBytesToStrip设为4,那么decoder返回的字节数为10,不包含长度字段,readableBytes为10
如果lengthAdjustment设为0,
那么encoder读完长度字段后,还要读取14+0=14个字节,但是buffer中没有这么多字节,
所以会继续等待收到另外一个包,才能继续处理,这样就错了
所以如果长度值不包含长度字段所占字节数,那么lengthAdjustment需要设为0
3.octet String的含义
octet现在就是字节的含义
字节串每个字节表示ascii值,例如字节串"0",那么这个字节十六进制表示为0x30