netty 使用ByteToMessage解决半包粘包
其实netty所有自带的decoder内置类都是继承与ByteToMessage的。
我们想要自定义自己的decoder就继承ByteToMessgae类就可以了。
前提:一般发送报文 报文中都会有数据的长度,或者规定了开头和结尾为特殊字符。
首先我们要知道netty发送和接收报文,都是事件驱动的,然后报文会读取到内核内存,后面再读取到用户内存,成为java可用的用户态。
在这个读取过程中,可能就会出现半包和粘包。
我们可以通过报文获取应该有的数据长度
in.markReaderIndex();//记录开始读的位置 int len = in.readableBytes();//获取可读的byteBuf的报文长度 //获取bytebuf字节开始处理 byte[] buff = new byte[len]; in.getBytes(in.readerIndex(), buff); offset = //数据长度的位置,这个是协议中规定好的,从buff转化获取数据长度 if (len > 最大报文长度) { in.skipByte() //如果超过最大报文长度还没找到数据位,就是垃圾报文 return; } if (len < offset) { in.resetReaderIndex();//重置读报文位置 return; } if (offset < 0) { ctx.close(); //异常数据 停止连接 } if (offset > in.readableBytes()) { in.resetReaderIndex(); //没有到达数据位说的报文长度 重置读报文位置 return; } //后面就可以写数据处理了 in.skip(offset);//跳过已经处理过的数据 //如果分析完数据长度还有剩余的报文 会自动累计到下一次的 所以不用怕粘包