JAVA实现报文解析:协议的数据类型和完整的报文结构解析

**JAVA实现GBT32960报文解析系列文章链接:**
JAVA实现GBT32960报文解析(一):协议的数据类型和完整的报文结构解析
JAVA实现GBT32960报文解析(二):数据包结构解析源码
JAVA实现GBT32960报文解析(三):0x01整车数据解析源码
JAVA实现GBT32960报文解析(四):0x02驱动电机数据解析源码
JAVA实现GBT32960报文解析(五):0x03燃料电池数据解析源码(待更…)
JAVA实现GBT32960报文解析(六):0x04发动机数据解析源码(待更…)
JAVA实现GBT32960报文解析(七):0x05车辆位置数据解析源码(待更…)
JAVA实现GBT32960报文解析(八):0x06极值数据解析源码(待更…)
JAVA实现GBT32960报文解析(九):0x07报警数据解析源码(待更…)
实战需求示例:车辆月度充电详情统计报表,含快充、慢充区分统计(待更…)



前言

在做报文的封装或者解析工作前,首先要对“各种进制”有一个简单的了解。大家可以通过百度百科对进制进行初步了解。

十六进制信息从阅读清晰到简洁传输:
在这里插入图片描述
在c语言中用添加前缀0x以表示十六进制数,也就是最前面的形式。但报文数据在需要作数据传输时,就需要更多的考虑到简洁化,因此我们的报文信息往往都是最后这种形式“一长串看似无规则的字符”。


一、国标协议中涉及的数据类型

在这里插入图片描述
通过对《GBT32960.3-2016》这份协议文档的阅读,能够发现以上各数据类型常用于使用的数据如下:

BYTE:各种状态或数值长度在3位数以内的数据;
WORD:数值长度在5位数以内。例如电压值、电流值、转速;
DWORD:数值长度在8位数以内。例如历史行驶里程数、坐标经纬度;
BYTE[,]:例如燃料电池的温度探针会涉及N个;
STRING:车辆VIN码、SIM卡的ICCID

二、满足相应数据类型的解析方法

结合以上对数据类型的了解,其实我们也就只需要准备3、4个针对十六进制字符解析的方法就能完全满足。

1.十六进制字符集转十六进制数组

代码如下(示例):

	String hexStr = "232303FE584C32434546355030414C30303730323301012D15071C110B320102030100000000010E0C58271000021013510065020101014F4E204E2055001F271005000633555501D2D2CE0601220D00011F0B1501014B010B49070300000450000000000801010C58271000600001600CBD0CD90CD00CCF0CE00CF00CE00CCB0CE10CE00CDF0CC80CC50CD30CCF0CE70CE50CE30CD90CE90CF60CEF0CE10CDF0CEA0CED0CE80CD10CDA0CEE0B150CD30CED0D000CCA0CED0CD60CDA0CED0CDC0CE70CF00CED0CDF0CF40CF30CDC0CE50CE00CEF0CE10CD20CDD0CE80CD60CEA0CDD0CE90CD90CD60CC90CCB0CDE0CCC0CD30CD60CE60CF20CE20CCC0CE90CE40CF80CA00CE50CE10CE90CE80CE20CF70CF50CEA0CCD0CF80CE50CDD0CE00CE10CE90CDD0CEB0CEE0CF40CF60CFC0CE109010100104B4A4A4A4949494A4A49494A4A4A4A4A5F";

国标报文大部分都是作数值处理,因此我没有采用第6行代码将"0x"带进去造成多余的处理。

	public static String[] hexStrToArray(String hexStr) {
        String[] array = new String[hexStr.length() / 2];
        int k = 2;
        for (int i = 0; i < array.length; i++) {
            array[i] = hexStr.substring(i * 2, k);
            //array[i] = "0x" + hexStr.substring(i * 2, k);
            k += 2;
        }
        return array;
    }

2.十六进制转数值

十六进制转数值其实很粗暴,直接使用java.lang包的Integer.parseInt(String, int)方法

代码如下(示例):

	int value = Integer.parseInt(hexStr, 16);

3.十六进制转二进制

代码如下(示例):

	public static String hexStr2Byte(String hexStr) {
        if (null == hexStr || 0 != hexStr.length() % 2)
            return null;
        String bString = "", tmp;
        for (int i = 0; i < hexStr.length(); i++) {
            tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexStr.substring(i, i + 1), 16));
            bString += tmp.substring(tmp.length() - 4);
        }
        return bString;
    }

4.十六进制转字符串

代码如下(示例):

	public static String hexStr2Str(String hexStr) {
        if (null == hexStr || hexStr.equals("")) {
            return null;
        }
        hexStr = hexStr.replace(" ", "");
        byte[] baKeyword = new byte[hexStr.length() / 2];
        try {
            for (int i = 0; i < baKeyword.length; i++) {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16));
            }
            hexStr = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hexStr;
    }

三、了解一个完整报文结构

一个完整的数据包结构应由起始符号、命令单元、唯一识别码(也就是车辆的VIN码)、数据加密方式、数据单元长度、数据单元和效验码组成。
在这里插入图片描述
注:在数据包中的数据单元会存在N个,而数据单元具体有哪些,则是根据“车辆实际状况”和“命令标识”而定。

1.数据单元有哪些?

以下是各种数据单元信息,对应的信息类型标识。
在这里插入图片描述
针对上表中备注所提及的详见位置内容,作一个简单的解读。如下:

0x01整车数据:车辆一般运营数据,以仪表盘数据为主;
0x02驱动电机数据:以电机控制器数据为主,车辆充电时可不传输;
0x03燃料电池数据:采用燃料电池驱动的车辆需传输此项,如无此种可充电储能子系统可不传输;
0x04发动机数据:采用油电混合的车辆需在使用发动机时传输此项数据;
0x05车辆位置数据:车辆GPS或北斗位置数据,一般使用车载终端的GPS信号,如车载终端无GPS数据,也可使用车辆数据;
0x06极值数据:车辆特征点数据,可作为绝大多数车辆故障判定依据;
0x07报警数据:车辆本身判定发生报警后上传的报警信息;
0x30~0x7F预留数据:单体信息预留信息类型;
其他:均为终端、平台交互、用户等角度的自定义数据;

2.从数据解析角度对数据包的划分

为什么没提及“命令标识”就直接讲数据单元有哪些信息类型,因为我打算先从数据进行分析的角度去做讲解。而不是一开始就根据命令标识来做业务的处理。

为了数据更简单的实体化使用,把完整的数据包直接拆分为两个大的分类,即:头部信息和各数据单元信息。
在这里插入图片描述


总结

从下一篇文章开始,正式对GB32960协议进行报文解析分享。将用一段命令标识为0x02【实际信息上报】的完整数据包进行逐字节解析


** 相关下载:**
国标协议GBT32960文档 (包含《GB/T 32960-2016 电动汽车远程服务与管理系统技术规范》完整的1、2、3部分)
源码部分:
JAVA解析GBT32960协议 - 数据包结构源码(另含ParseUtils.java和BCCVerifyUtils.java两个工具类)
JAVA解析GBT32960协议 - 0x01整车数据源码
JAVA解析GBT32960协议 - 0x02驱动电机数据源码
JAVA解析GBT32960协议 - 0x03燃料电池数据源码(待更…)
JAVA解析GBT32960协议 - 0x04发动机数据源码(待更…)
JAVA解析GBT32960协议 - 0x05车辆位置数据源码(待更…)
JAVA解析GBT32960协议 - 0x06极值数据源码(待更…)
JAVA解析GBT32960协议 - 0x07报警数据源码(待更…)

  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
104协议是一种用于数据传输的协议,通常用于电力行业。在Java解析104协议报文内容需要使用特定的库或框架,比如IEC104、JT104等。 首先,需要创建一个与104服务器建立连接的通信通道。可以使用Java提供的Socket类与服务器进行连接。 连接建立后,可以通过通道读取和写入报文。 在104协议中,报文有固定的结构,包括报文长度、类型、数据等字段。要解析报文内容,首先要读取报文长度,以确定报文的大小。 然后,根据报文的类型字段,可以进一步解析报文内容。报文内容可以是单个数据对象,也可以是多个数据对象的集合。 每个数据对象都有自己的标识、类型和值。可以通过解析报文中的标识字段,确定数据对象的唯一性。然后根据类型字段,确定数据对象的数据类型。最后,根据值字段,获取数据对象的具体数值。 解析报文内容还需要处理报文的控制信息。报文中的控制信息包括控制字段、传输原因等。根据控制字段,可以确定报文的目的(是读取还是写入数据)。传输原因则指示了报文的具体目的和动作。 最后,解析报文内容后,还需要根据需要进行相应的处理,比如对数据进行分析、存储或展示等。 总之,Java解析104协议报文内容需要使用特定的库或框架,并按照报文的固定结构,读取报文长度,确定报文类型,解析报文内容和控制字段,并进行相应的处理。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值