Netty自定义序列化编解码器的解决粘包/半包问题的编解码方案方案二:完全自定义

Netty自定义序列化编解码器的解决粘包/半包问题的编解码方案方案一:使用LengthFieldPrepender与LengthFieldBasedFrameDecoder

  • 原理

通过改造编解码器,将LengthFieldPrepender与LengthFieldBasedFrameDecoder的功能直接写在自定义编解码器中,这样就不需要使用LengthFieldPrepender与LengthFieldBasedFrameDecoder了

  • 代码

1.CustomV2Encoder

/**
 * @author pdc
 */
public class CustomV2Encoder extends MessageToByteEncoder {

    @Override
    public void encode(ChannelHandlerContext ctx, Object in, ByteBuf out) throws Exception {
        //使用hessian序列化对象
        byte[] data = HessianSerializer.serialize(in);
        //先写入消息的长度作为消息头
        out.writeInt(data.length);
        //最后写入消息体字节数组
        out.writeBytes(data);
    }
}

2.CustomV2Decoder

/**
 * @author pdc
 */
public class CustomV2Decoder extends ByteToMessageDecoder {

    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        //读取消息头,整个消息的长度字段
        if (in.readableBytes() < 4) {
            return;
        }
        in.markReaderIndex();
        int dataLength = in.readInt();//读取一个规定的int,即长度
        if (dataLength < 0) {
            ctx.close();
        }
        //读取字节数组,直到读取的字节数组长度等于dataLength
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        byte[] data = new byte[dataLength];
        in.readBytes(data);
        //将字节数组使用Hession反序列化为对象
        Object obj = HessianSerializer.deserialize(data);
        out.add(obj);
    }
}

3.CustomServer:修改如下

//配置自定义序列化解码工具
ch.pipeline().addLast(new CustomV2Decoder());
//配置自定义序列化编码工具
ch.pipeline().addLast(new CustomV2Encoder());

ch.pipeline().addLast(new CustomServerHandler());

4.CustomClient:修改如下

//配置自定义序列化解码工具
ch.pipeline().addLast(new CustomV2Decoder());
//配置自定义序列化编码工具
ch.pipeline().addLast(new CustomV2Encoder());
ch.pipeline().addLast(new CustomClientHandler());
  • 运行

先运行CustomServer的main,再运行CustomClient的main即可

猜你喜欢

转载自blog.csdn.net/qq_41594698/article/details/94715389