何时使用帧解码

时间:2018-07-20 14:52:58

标签: netty

我不清楚,是否需要在基于MessageToMessageDecoder构建自定义POJO解码器时使用像LineBasedFrameDecoder这样的帧解码器?

在StringDecoder的Ne​​tty源代码中指出frame decoder must be used together with the StringDecoder

我想是的,为什么买?

2 个答案:

答案 0 :(得分:0)

我问自己这是否应该作为答案;您可以使用所需的任何实现。 JavaDocs提供了有关如何编码/解码字符串数据的示例。您可以实现自己的处理程序并确定字符串的开始和停止。

例如,我实现了自己的数据包协议,该协议混合了在线视频游戏的大量数据。所以我通过先读取varint然后再读取字符串来解码我的字符串。我可以采用相同的逻辑,并创建自己的处理程序以解码StringDecoder处理程序之前的字符串长度。

编码器

public static ByteBuf encodeString(ByteBuf out, String value, Charset charset) {
    byte[] bytes = value.getBytes(charset);
    encodeArray(out, bytes);
    return out;
}

public static ByteBuf encodeArray(ByteBuf out, byte[] bytes) {
    int length = bytes.length;
    encodeInteger(out, length);
    out.writeBytes(bytes);
    return out;
}

public static ByteBuf encodeInteger(ByteBuf out, int number) {
    return encodeInt(out, number, computeUInt32Size(number));
}

public static ByteBuf encodeInt(ByteBuf out, int number, int numBytes) {
    int originalIndex = out.writerIndex();
    int adjustedI = originalIndex + numBytes;
    final int capacity = out.capacity();
    if (adjustedI > capacity) {
        out.capacity(adjustedI);
    }
    out.writerIndex(out.writerIndex() + numBytes);
    for (int i = adjustedI - 1; i >= originalIndex; i--) {
        int curByte = (number & 0x7F);
        if (i != (adjustedI - 1)) {
            curByte |= 0x80;
        }
        out.setByte(i, curByte);
        number >>>= 7;
    }
    return out;
}

public static int computeUInt32Size(int value) {
    if ((value & (~0 <<  7)) == 0) {
        return 1;
    }
    if ((value & (~0 << 14)) == 0) {
        return 2;
    }
    if ((value & (~0 << 21)) == 0) {
        return 3;
    }
    if ((value & (~0 << 28)) == 0) {
        return 4;
    }
    return 5;
}

解码器

public static String unsafeDecodeString(ByteBuf in, Charset standardCharsets) {
    byte[] bytes = unsafeDecodeArray(in);
    return new String(bytes, standardCharsets);
}

public static byte[] unsafeDecodeArray(ByteBuf in) {
    int len = unsafeDecodeInteger(in);
    return unsafeDecodeArray(in, len);
}

public static byte[] unsafeDecodeArray(ByteBuf in, int len) {
    byte[] bytes = new byte[len];
    in.readBytes(bytes, 0, len);
    return bytes;
}

// This is unsafe as we do not check readable bytes, is safe if apart of a packet read all at // once
 public static int unsafeDecodeInteger(ByteBuf in) {
    int n = 0;
    for (int i = 0; i <= 8; i++) {
        int curByte = in.readByte();
        n = (n << 7) | (curByte & 0x7f);
        if ((curByte & 0x80) == 0) {
            break;
        }
    }
    return n;
}

答案 1 :(得分:0)

Netty源代码中的注释引发了一个奇怪的问题。

要回答我自己的问题:这取决于! 如果没有固定长度的数据帧,则需要某种方式让客户端和服务器双方就何时结束数据帧达成共识–完成。它可能很简单,例如\ r \ n(回车+换行符)或其他已同意的字符。