netty自动解包用
LengthFieldBasedFrameDecoder
假如一个数据包 header 4 + length 3+ data+ check 2,返回数据需要完整包
参数用4,3,2,0,一顿操作猛如虎,结果等了很久没得到一个包完整数据。
多次仔细查看不用netty插件自动解包数据和其他成功实例区别,发现原来netty自动解包长度字段是16进制,假如一个包长16,应该0x 00 00 10,但本实例返回0x 30 31 36,好吧这个就是字符型的016,经过同事网上借鉴 Netty源码分析 (十一)----- 拆包器之LengthFieldBasedFrameDecoder - chen_hao - 博客园
后来自定义了长度解析,然后修改了参数4,3,0,0就好了
public class CustomLengthFieldBasedFrameDecoder extends LengthFieldBasedFrameDecoder {
public CustomLengthFieldBasedFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) {
super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
}
/**
*offset=lengthFieldOffset
*/
@Override
protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order) {
buf = buf.order(order);
long frameLength = 0;
switch (length) {
case 1:
frameLength = buf.getUnsignedByte(offset);
break;
case 2:
frameLength = buf.getUnsignedShort(offset);
break;
case 3:
byte[] data=new byte[length];
ByteBuf tmpBuf=buf.copy(offset,length);
tmpBuf.readBytes(data);
String lengthStr=new String(data, CharsetUtil.US_ASCII);
try{
frameLength = Integer.valueOf(lengthStr)+ UPSCommand.UPS_MIN_PACKAGE_CHECKSUM_LENGTH;
}catch (Exception ex){
frameLength = buf.getUnsignedMedium(offset);
ex.printStackTrace();
}
break;
case 4:
frameLength = buf.getUnsignedInt(offset);
break;
case 8:
frameLength = buf.getLong(offset);
break;
default:
throw new DecoderException(
"unsupported lengthFieldLength: " + length + " (expected: 1, 2, 3, 4, or 8)");
}
return frameLength;
}
}
由此可见标准的协议确实能节省人力,但是高手程序员就是能面对各种困难勇往直前
--------------------------------
顺便记一下一个小知识有符号byte和无符号int实际值
-1 对应255 ,-2 对应 254 ,-127 对应129, -128 对应 128,0到127是直接对应