add LengthFieldBasedFrameDecoder
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -48,4 +48,10 @@ public class Constants {
|
||||
* 编码解码 byte 数组固定长度
|
||||
*/
|
||||
public static int DECODER_FRAMELENGTH = 100;
|
||||
|
||||
public static final int MAX_FRAME_LENGTH = 1024 * 1024; //最大长度
|
||||
public static final int LENGTH_FIELD_LENGTH = 4; //长度字段所占的字节数
|
||||
public static final int LENGTH_FIELD_OFFSET = 2; //长度偏移
|
||||
public static final int LENGTH_ADJUSTMENT = 0;
|
||||
public static final int INITIAL_BYTES_TO_STRIP = 0;
|
||||
}
|
||||
|
@@ -47,19 +47,18 @@ public class NettyUtil {
|
||||
oos.writeObject(obj);
|
||||
oos.flush();
|
||||
|
||||
byte[] bytes = bos.toByteArray();
|
||||
if (bytes.length > Constants.DECODER_FRAMELENGTH) {
|
||||
logger.error("bytes length should not bigger than {}", Constants.DECODER_FRAMELENGTH);
|
||||
return null;
|
||||
} else if (bytes.length < Constants.DECODER_FRAMELENGTH) {
|
||||
byte[] result = new byte[Constants.DECODER_FRAMELENGTH];
|
||||
// if (bytes.length > Constants.DECODER_FRAMELENGTH) {
|
||||
// logger.error("bytes length should not bigger than {}", Constants.DECODER_FRAMELENGTH);
|
||||
// return null;
|
||||
// } else if (bytes.length < Constants.DECODER_FRAMELENGTH) {
|
||||
// byte[] result = new byte[Constants.DECODER_FRAMELENGTH];
|
||||
//
|
||||
// // 如果长度不足,填充
|
||||
// System.arraycopy(bytes, 0, result, 0, bytes.length);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// 如果长度不足,填充
|
||||
System.arraycopy(bytes, 0, result, 0, bytes.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
public static Object toObject(byte[] bts) throws IOException, ClassNotFoundException {
|
||||
|
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.did.netty;
|
||||
|
||||
import io.github.ehlxr.did.common.NettyUtil;
|
||||
import io.github.ehlxr.did.common.Try;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-02-08 22:07.
|
||||
*/
|
||||
public class MyProtocolBean {
|
||||
// 类型(系统编号 0xA 表示A系统,0xB 表示B系统)
|
||||
private byte type;
|
||||
|
||||
// 信息标志 0xA 表示心跳包 0xB 表示超时包 0xC 业务信息包
|
||||
private byte flag;
|
||||
|
||||
// 内容长度
|
||||
private int length;
|
||||
|
||||
// 内容
|
||||
private byte[] content;
|
||||
|
||||
public MyProtocolBean(byte type, byte flag, int length, byte[] content) {
|
||||
this.type = type;
|
||||
this.flag = flag;
|
||||
this.length = length;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public byte getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public byte getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(byte flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(byte[] content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MyProtocolBean{" +
|
||||
"type=" + type +
|
||||
", flag=" + flag +
|
||||
", length=" + length +
|
||||
", content=" + Try.of(NettyUtil::toObject).apply(content).get() +
|
||||
'}';
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.did.netty;
|
||||
|
||||
import io.github.ehlxr.did.netty.MyProtocolBean;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-02-08 22:09.
|
||||
*/
|
||||
public class MyProtocolDecoder extends LengthFieldBasedFrameDecoder {
|
||||
private static final int HEADER_SIZE = 6;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
|
||||
//在这里调用父类的方法,实现指得到想要的部分,我在这里全部都要,也可以只要body部分
|
||||
in = (ByteBuf) super.decode(ctx, in);
|
||||
|
||||
if (in == null) {
|
||||
return null;
|
||||
}
|
||||
if (in.readableBytes() < HEADER_SIZE) {
|
||||
throw new Exception("字节数不足");
|
||||
}
|
||||
//读取type字段
|
||||
byte type = in.readByte();
|
||||
//读取flag字段
|
||||
byte flag = in.readByte();
|
||||
//读取length字段
|
||||
int length = in.readInt();
|
||||
|
||||
if (in.readableBytes() != length) {
|
||||
throw new Exception("标记的长度不符合实际长度");
|
||||
}
|
||||
//读取body
|
||||
byte[] bytes = new byte[in.readableBytes()];
|
||||
in.readBytes(bytes);
|
||||
|
||||
return new MyProtocolBean(type, flag, length, bytes);
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2020 xrv <xrg@live.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.ehlxr.did.netty;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
/**
|
||||
* @author ehlxr
|
||||
* @since 2021-02-08 22:12.
|
||||
*/
|
||||
public class MyProtocolEncoder extends MessageToByteEncoder<MyProtocolBean> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, MyProtocolBean msg, ByteBuf out) throws Exception {
|
||||
if (msg == null) {
|
||||
throw new Exception("msg is null");
|
||||
}
|
||||
out.writeByte(msg.getType());
|
||||
out.writeByte(msg.getFlag());
|
||||
out.writeInt(msg.getLength());
|
||||
out.writeBytes(msg.getContent());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user