• netty之bytebuf粘包、分包


    之前开发一款上位机软件就被这个问题困扰的够呛,原因是因为当时我完全不知道还存在这样的问题,直到后来用了数据监控软件才发现了我那些参差不齐的数据包,又结合了之前在网上检索过的文章,最终才了解到了原来还有这么一回事。

    所以,这次学netty的时候特意留了个心眼,提前搜索了一下netty是否也存在粘包这类问题,答案是存在!行吧,那就研究一下怎么解决吧。以下内容来自于笔者自学以及根据个人历史经验总结而成,暂时没在企业项目中处理过相关问题,不保证正确

    首先,我自定义了一个非常简单的解码器,其实并不具备解码功能,目的就是为了证实我的一个猜测:

    public class DecodeHandler extends ByteToMessageDecoder {
        @Override
        protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
            System.out.println(byteBuf.writerIndex());
        }
    }

    在解码器中,输出的是写索引的位置。

    然后,我开始尝试触发解码器,发现当我不断向byteBuf中写入内容后,写索引也不断增长,我写入两字节,写索引就增大2,写入三字节,写索引就增加3。由此,我猜测每次接收数据准备进行解码的bytebuf都是同一个!而不是新建的bytebuf!

    然后,就要根据实际情况来分析了,也就是要看数据的具体格式来分析。比如我之前遇到的那种返回值,是一个定长数组,没有固定的开头标识,除了依靠长度来解析我实在是想不出怎么解析。

    但是,还有一种情况,数据是有开头标识的,比如每个数据包都以0x23,0x23来作为起始值。那么可以先找到数据的起始值在哪里。

    private void find(ByteBuf buf) {
            int count = buf.readableBytes();
            for (int index = buf.readerIndex(); index < count - 2; index++) {
                if (buf.getByte(index) == 0x23 & buf.getByte(index + 1) == 0x23) {
                    buf.readerIndex(index);
                    return;
                }
            }
            buf.readerIndex(count - 1);
        }

    比如可以这样找,或者也可以根据你的实际情况选择是否直接跳过开头标识。

    然后,确定了读索引的位置就比较好办了,接下来的解析方式就看数据的具体格式了,在解析之前有必要检测一下数据长度是否完整,如果不完整,可以选择跳过这一波解析,等待数据接收完整再解析(记得要将读索引恢复到正确的位置)。

  • 相关阅读:
    Windows 下搭建Android开发环境
    浅谈C/C++中运算符的优先级、运算符的结合性以及操作数的求值顺序
    更新Android SDK到3.0版本时,遇到Failed to rename directory E:\android\tools to E:\android\temp\ToolPackage.old01问题
    单词计数 soj1076
    拓扑排序
    浅谈C和C++中的const关键字
    快速排序
    拓扑排序 soj1075
    集合划分问题
    浅谈C/C++中的顺序点和副作用
  • 原文地址:https://www.cnblogs.com/wxdmw/p/13476029.html
Copyright © 2020-2023  润新知