diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/decoder/StartAndLengthFieldFrameDecoder.java b/jsowell-netty/src/main/java/com/jsowell/netty/decoder/StartAndLengthFieldFrameDecoder.java index b32b9b6ff..d7e6cdc7f 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/decoder/StartAndLengthFieldFrameDecoder.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/decoder/StartAndLengthFieldFrameDecoder.java @@ -5,10 +5,14 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import lombok.extern.slf4j.Slf4j; +import java.nio.charset.StandardCharsets; import java.util.List; @Slf4j public class StartAndLengthFieldFrameDecoder extends ByteToMessageDecoder { + private static final int HEADER_LENGTH_DNY = 3; // "DNY" 包头的长度 + private static final int HEADER_LENGTH_68 = 1; // 68 包头的长度 + // 起始标志 private int HEAD_DATA; @@ -24,8 +28,8 @@ public class StartAndLengthFieldFrameDecoder extends ByteToMessageDecoder { */ public final int BASE_LENGTH = 1 + 1; - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { + // @Override + protected void decode2(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { // 可读长度必须大于基本长度 if (buffer.readableBytes() <= BASE_LENGTH) { log.warn("可读字节数:{}小于基础长度:{}", buffer.readableBytes(), BASE_LENGTH); @@ -79,4 +83,91 @@ public class StartAndLengthFieldFrameDecoder extends ByteToMessageDecoder { out.add(frame); } + protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { + // 记录包头开始的index + int beginReader; + + while (true) { + if (buffer.readableBytes() < Math.min(HEADER_LENGTH_DNY, HEADER_LENGTH_68)) { + return; // 数据长度不足,等待更多数据 + } + + // 获取包头开始的index + beginReader = buffer.readerIndex(); + buffer.markReaderIndex(); + + // 读到了协议的开始标志,结束while循环 + if (buffer.getUnsignedByte(beginReader) == HEAD_DATA) { + break; + } + + // 未读到包头,略过一个字节 + buffer.resetReaderIndex(); + buffer.readByte(); + } + + // 检查包头是否是 "DNY" + if (buffer.readableBytes() >= HEADER_LENGTH_DNY) { + byte[] headerBytes = new byte[HEADER_LENGTH_DNY]; + buffer.getBytes(beginReader, headerBytes, 0, HEADER_LENGTH_DNY); + String header = new String(headerBytes, StandardCharsets.UTF_8); + + if ("DNY".equals(header)) { + // 处理 DNY 协议 + decodeDnyMessage(buffer, out, beginReader); + return; + } + } + + // 检查包头是否是 68 协议 + if (buffer.readableBytes() >= HEADER_LENGTH_68) { + if (buffer.getUnsignedByte(beginReader) == 0x68) { + // 处理 68 协议 + decode68Message(buffer, out, beginReader); + return; + } + } + + // 未知协议,还原读指针 + buffer.resetReaderIndex(); + } + + private void decode68Message(ByteBuf buffer, List out, int beginReader) { + if (buffer.readableBytes() < HEADER_LENGTH_68 + 1) { + buffer.readerIndex(beginReader); + return; + } + + // 消息的长度 + int length = buffer.getUnsignedByte(beginReader + HEADER_LENGTH_68); + if (buffer.readableBytes() < HEADER_LENGTH_68 + 1 + length) { + buffer.readerIndex(beginReader); + return; + } + + // 读取 data 数据 + ByteBuf frame = buffer.retainedSlice(beginReader, HEADER_LENGTH_68 + 1 + length); + buffer.readerIndex(beginReader + HEADER_LENGTH_68 + 1 + length); + out.add(frame); + } + + private void decodeDnyMessage(ByteBuf buffer, List out, int beginReader) { + if (buffer.readableBytes() < HEADER_LENGTH_DNY + 1) { + buffer.readerIndex(beginReader); + return; + } + + // 消息的长度 + int length = buffer.getUnsignedByte(beginReader + HEADER_LENGTH_DNY); + if (buffer.readableBytes() < HEADER_LENGTH_DNY + 1 + length) { + buffer.readerIndex(beginReader); + return; + } + + // 读取 data 数据 + ByteBuf frame = buffer.retainedSlice(beginReader, HEADER_LENGTH_DNY + 1 + length); + buffer.readerIndex(beginReader + HEADER_LENGTH_DNY + 1 + length); + out.add(frame); + } + }