package com.js.kbt.socket; import java.nio.ByteOrder; import java.nio.charset.Charset; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; public class MyProtocolDecoder extends LengthFieldBasedFrameDecoder { private static final String HEXES = "0123456789ABCDEF"; private static final int HEADER_SIZE = 4; /** * * @param maxFrameLength 帧的最大长度 * @param lengthFieldOffset length字段偏移的地址 * @param lengthFieldLength length字段所占的字节长 * @param lengthAdjustment 修改帧数据长度字段中定义的值,可以为负数 因为有时候我们习惯把头部记入长度,若为负数,则说明要推后多少个字段 * @param initialBytesToStrip 解析时候跳过多少个长度 * @param failFast 为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异 */ public MyProtocolDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) { super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast); } protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order) { buf = buf.order(order); long frameLength; byte b1 = buf.getByte(offset); byte b2 = buf.getByte(offset + 1); StringBuilder hex = new StringBuilder(); String s1 = hex.append(HEXES.charAt((b2 & 0xF0) >> 4)).append(HEXES.charAt((b2 & 0x0F))) .append(HEXES.charAt((b1 & 0xF0) >> 4)).append(HEXES.charAt((b1 & 0x0F))).toString(); frameLength = Integer.parseInt(s1, 16) - 4;//去掉头部的FAAF0000四位 System.out.println("getUnadjustedFrameLength解析长度:"+frameLength); return frameLength; } @Override protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { System.out.println("解析长度decode:"); //在这里调用父类的方法,实现指得到想要的部分,我在这里全部都要,也可以只要body部分 in = (ByteBuf) super.decode(ctx,in); if(in == null){ return null; } if(in.readableBytes()> 4)).append(HEXES.charAt((b2 & 0x0F))) // .append(HEXES.charAt((b1 & 0xF0) >> 4)).append(HEXES.charAt((b1 & 0x0F))).toString(); // // int length = Integer.parseInt(s1, 16); // System.out.println("解析长度:"+length); // if(in.readableBytes()!=length){ // throw new Exception("标记的长度不符合实际长度"); // } //读取body byte []bytes = new byte[in.readableBytes()]; in.readBytes(bytes); return bytes; } }