继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即可