Netty自定义数据包协议
粘包和分包出现的原因是:没有一个稳定数据结构
解决办法: 分割符
长度 + 数据
*
* 数据包格式
* +——----——+——-----——+——----——+——----——+——-----——+
* | 包头 | 模块号 | 命令号 | 长度 | 数据 |
* +——----——+——-----——+——----——+——----——+——-----——+
*
* 包头4字节
* 模块号2字节short
* 命令号2字节short
* 长度4字节(描述数据部分字节长度)
创建encoder 和 decoder 分别 加入pipeline 中
public class RpcDecoder extends ByteToMessageDecoder { private Class<?> genericClass; public RpcDecoder(Class<?> genericClass) { this.genericClass = genericClass; } @Override public void decode(ChannelHandlerContext ctx, ByteBuf in, List
public class RpcEncoder extends MessageToByteEncoder { private Class<?> genericClass; public RpcEncoder(Class<?> genericClass) { this.genericClass = genericClass; } @Override public void encode(ChannelHandlerContext ctx, Object in, ByteBuf out) throws Exception { if (genericClass.isInstance(in)) { byte[] data = SerializationUtil.serialize(in); out.writeInt(data.length); out.writeBytes(data); } } }
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List
buffer里面数据未被读取完怎么办
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List
数据缓存在 cumulation中
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof ByteBuf) { RecyclableArrayList out = RecyclableArrayList.newInstance(); try { ByteBuf data = (ByteBuf) msg; first = cumulation == null; //第一次请求 cumulation 为 null true if (first) { cumulation = data; } else { cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data); // 第二次请求时进入 将新的信息追加到cumulation后面 } callDecode(ctx, cumulation, out); } catch (DecoderException e) { throw e; } catch (Throwable t) { throw new DecoderException(t); } finally { if (cumulation != null && !cumulation.isReadable()) { cumulation.release(); cumulation = null; } int size = out.size(); for (int i = 0; i < size; i ++) { ctx.fireChannelRead(out.get(i)); } out.recycle(); } } else { ctx.fireChannelRead(msg); } }