一、前情提要
果然话不能说太满~~ 神马完美解决~~ 果然还是遇到问题了。单纯加in.skipBytes(in.readableBytes());这一句代码会造成数据传递过去的都是一个EmptyByteBufBE ... ...
- 解码断点是有数据接收到的可读长度416个字节
- 到handler里的channelRead0中看到readerIndex已然是416,因为是在解码的时候是直接把与原本的ByteBuf传递到handler里,但是在解码的最后逻辑里我又读取了,跳过读取其实就是读取,只是一次性移动完readerIndex坐标指向,也能看出来skipBytes这我写在前面和后面都无区别,在数据流向handler的时候,都是最终被读完的。
- 这样就导致服务端收到的报文信息都是空的
- 前情代码
@Override protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception { if(in.readableBytes() <= 0){ log.info("***********当前无数据报文,无需解码***********"); return; } SocketData data = new SocketData(in); data.setpId(this.pId); ChannelData channelData = new ChannelData(data); ReferenceCountUtil.retain(in); out.add(channelData); in.skipBytes(in.readableBytes()); }
二、解决方案
- copy一份ByteBuf,把原本的这份读取掉(或者说跳过读取),然后传递副本。
代码
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() <= 0){
log.info("***********当前无数据报文,无需解码***********");
return;
}
ByteBuf dup = in.retainedDuplicate();
SocketData data = new SocketData(dup);
data.setpId(this.pId);
ChannelData channelData = new ChannelData(data);
ReferenceCountUtil.retain(in);
out.add(channelData);
in.skipBytes(in.readableBytes());
}
- 解码器
- handler 里 byteBuf的readerIndex已经是0开始了,因为这是副本传回来的,没有经过读取。
- 到服务端就有数据了