栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Netty新增解析数据包指定长度功能

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Netty新增解析数据包指定长度功能

项目场景:

老师安排的一个体检系统,其中需要使用身份证读卡器读取用户信息,并在前端展示相关信息,方便用户查询,进行下一步操作。

项目中使用了Netty构建RPC服务端,提供Socket和WebSocket连接和数据交互功能。身份证读卡器客户端是C++客户端开发,使用Socket建立与Netty服务端连接,并交互数据。


项目中遇到两个需要解决问题

问题一
1.1 描述

C++客户端向Netty服务端发送数据,Netty服务器因为不知道数据包大小,会提前结束

  • 真实传输数据:
{
   "data" : {
      "idCard" : "360123xxxx",
      "name" : "xxx"
   },
   "key" : "00-50-56-C0-00-01",
   "keyName" : "mac",
   "module" : "examination",
   "type" : "00"
}
  • 实际接受数据:
1.2 原因分析:

通过查看处理代码:

    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("接收到来自客户端的信息:{}", ctx.channel().remoteAddress().toString());

        String requestData = (String)msg;
        log.info("收到socket消息:"+ requestData);
        Channel channel = ctx.channel();
    }

    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

在调用channelRead0()函数,可能会出现还没有读取完数据,就提前调用channelReadComplete()函数进行停止读取,刷新操作。

1.3 解决方案:

在ChannelPipeline中添加 LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)解码器,根据数据包前4个字节(unsignedInt)进行解析,获取数据包长度。根据已知长度获取数据。


问题二
2.1 描述

在根据上面的解决方式进行操作后,发现一直无法正常解析数据包,会提前结束。

2.2 原因分析:

通过进行查看C++客户端传来的数据包,和通过Debug发现:

  • 数据包
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 15 00 00 00 7b 0a 20 20 20 22 74 79 70 65 22 20 |....{.   "type" |
|00000010| 3a 20 22 31 31 22 0a 7d 0a                      |: "11".}.       |
+--------+-------------------------------------------------+----------------+
  • Debug

    可以发现,其实 LengthFieldBasedFrameDecoder()默认使用大端解析数据包,而实际传来数据是小端方式,因此会出现解析数据包长度长于实际数据包长度。

2.3 解决方案:

在 LengthFieldBasedFrameDecoder()上面指定使用小端解析就可以了

ctx.pipeline().addLast("length-decoder",new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN,Integer.MAX_VALUE, 0, 4, 0, 4,true));
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/934042.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号