C#实现 CAT021报文格式解析
来源:互联网 发布:淘宝宝婴儿秋冬服装 编辑:程序博客网 时间:2024/05/16 08:17
这几天接到一个小项目,需要解析 CAT021报文,一看文档全是英文,心就凉了半截。费了九牛二虎之力终于看懂了报文解析的规则,接下来我就对我从二进制数据到实例出各数据项相应的对象的过程做一个小结,希望能帮到有需要的朋友。
首先是总体方法:
/// <summary> /// 接收到的数据解析 /// </summary> /// <param name="datas"></param> /// <returns></returns> private static DataBlock DateParser(byte[] datas) { int cat = 0; int len = 0; byte[] fspecbytes; byte[] temp = new byte[4]; DataBlock datablock = new DataBlock(); Array.Copy(datas, 0, temp, 0, 1); cat = BitConverter.ToInt32(temp, 0); Array.Clear(temp, 0, temp.Length); Array.Copy(datas, 1, temp, 0, 2); Array.Reverse(temp, 0, 2); len = BitConverter.ToInt32(temp, 0); Array.Clear(temp, 0, temp.Length); fspecbytes = getFspecBytes(datas); List<DatagramUap> dataitems = DatagramParser(fspecbytes, len,datas); datablock.Cat = cat; datablock.Len = len; datablock.Dataitem = dataitems; return datablock; }
接下来是核心方法:
/// <summary> /// 解析出数据项的实体列表 /// </summary> /// <param name="fspecbytes"></param> /// <param name="len"></param> /// <param name="datas"></param> /// <returns></returns> private static List<DatagramUap> DatagramParser(byte[] fspecbytes, int len, byte[] datas) { int count = 0; List<DatagramUap> dataitems = new List<DatagramUap>(); while (count < fspecbytes.Length) { int index = 7; while (index > 0) { byte[] tempbytes = new byte[fspecbytes.Length]; Array.Copy(fspecbytes, tempbytes, fspecbytes.Length); tempbytes[count] <<= 7 - index; tempbytes[count] >>= 7; byte[] temp1 = new byte[4]; temp1[0] = tempbytes[count]; if (BitConverter.ToInt32(temp1, 0) != 0) { DatagramUap datagramuap = InitDategram(count, index); dataitems.Add(datagramuap); } index--; } count++; } int currnetbytenum = 0; byte[] databytes = new byte[len - 3 - fspecbytes.Length]; Array.Copy(datas, 3 + fspecbytes.Length, databytes, 0, databytes.Length); foreach (DatagramUap dataitem in dataitems) { byte[] bytes = new byte[dataitem.Len]; Array.Copy(databytes, currnetbytenum, bytes, 0, bytes.Length); dataitem.Databytes = bytes; currnetbytenum += dataitem.Len; } return dataitems; }
根据位置确定数据项:
/// <summary> /// 根据位置确定数据项 /// </summary> /// <param name="count">符号字节第几个字节</param> /// <param name="index">字节第几位</param> /// <returns></returns> private static DatagramUap InitDategram(int count, int index) { DatagramUap datagram = new DatagramUap(); switch (count) { case 0: Dategram0(index,datagram); break; case 1: Dategram1(index, datagram); break; case 2: Dategram2(index, datagram); break; case 3: Dategram3(index, datagram); break; case 4: Dategram4(index, datagram); break; } return datagram; }
解析出标识符所占的字节:
/// <summary> /// 解析出标识符所占的字节 /// </summary> /// <param name="dates"></param> /// <returns></returns> private static byte[] getFspecBytes(byte[] dates) { int count = 3; byte[] fspecbytes; //如果下一个字节是标识符 while (IsMoreFspec(dates[count])) { count++; } //确定标识符字节数 fspecbytes = new byte[count - 2]; Array.Copy(dates, 3, fspecbytes, 0, fspecbytes.Length); return fspecbytes; }
判断下一个字节是否是符号字节:
/// <summary> /// 判断下一个字节是否是符号字节 /// </summary> /// <param name="temp"></param> /// <returns></returns> private static Boolean IsMoreFspec(byte temp) { Boolean ismore = false; byte[] tempbytes = new byte[4]; temp <<= 7; temp >>= 7; tempbytes[0] = temp; if (BitConverter.ToInt32(tempbytes, 0) == 0) { ismore = false; } else { ismore = true; } return ismore; }
当为第1个描述符字节时,初始化对象,其他初始化对象过程一样,看源代码就知道:
/// <summary> /// 当为第1个描述符字节时,初始化对象 /// </summary> /// <param name="index"></param> /// <param name="datagram"></param> private static void Dategram0(int index, DatagramUap datagram) { switch (index) { case 7: datagram.Dateitemname = "数据源识别"; datagram.DateitemNum = "1021/010"; datagram.Fra = 1; datagram.Len = 2; break; case 6: datagram.Dateitemname = "目标报告描述符"; datagram.DateitemNum = "1021/040"; datagram.Fra = 2; datagram.Len = 2; break; case 5: datagram.Dateitemname = "日时间"; datagram.DateitemNum = "1021/030"; datagram.Fra = 3; datagram.Len = 3; break; case 4: datagram.Dateitemname = "在WGS-84坐标中的位置"; datagram.DateitemNum = "1021/130"; datagram.Fra = 4; datagram.Len = 8; break; case 3: datagram.Dateitemname = "目标地址"; datagram.DateitemNum = "1021/080"; datagram.Fra = 5; datagram.Len = 3; break; case 2: datagram.Dateitemname = "几何高度"; datagram.DateitemNum = "1021/140"; datagram.Fra = 6; datagram.Len = 2; break; case 1: datagram.Dateitemname = "品质因素"; datagram.DateitemNum = "1021/090"; datagram.Fra = 7; datagram.Len = 2; break; } }
最后再测试一下:
static void Main(string[] args) { byte[] temp = { 0x15, 0x00, 0x18, 0xE9, 0x95, 0x80, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x78, 0x0A, 0x4E, 0x10, 0x08, 0x7D, 0xFB, 0xD8, 0x7F, 0xF6, 0xF6 }; DataBlock datablock = DateParser(temp); }
其他方法或类如果需要可以留言。这个解析过程,从看文档到写这个demo花了大概一下午时间,所以肯定有很多地方考虑不周,希望大家不要吐槽~~
具体到每个数据项的值我还没有做,不过这个都解析出来了,那后面的也就渣渣呐~~~
0 0
- C#实现 CAT021报文格式解析
- 解析HTTP报文格式
- 解析HTTP报文格式
- SNMP PDU报文格式解析
- ARP 报文格式 完全解析
- HTTP请求报文格式解析
- 特殊格式报文的实现
- SNMP的报文格式以及解析
- 网络:传输层 TCP报文格式解析
- 依据XML定义报文格式解析数据
- HTTP报文、GET和POST格式解析
- HTTP的报文格式、GET和POST格式解析
- HTTP的报文格式、GET和POST格式解析
- 报文格式【定长报文】
- ARP/RARP(地址解析/反向地址解析)报文格式
- 报文格式
- 报文格式
- java文件上传报文解析与实现
- SpringMVC @RequestBody 接收Json数组对象
- TableViewCell的3D翻转特效
- c# 无边框窗体鼠标点击移动方法
- 说说悠百佳加盟品牌的价格骗局
- 博客开始
- C#实现 CAT021报文格式解析
- 学习Javascript闭包(Closure)
- 图像的运算--点运算
- Hashcode的作用
- Wex5 通过ajax访问远程数据
- 按钮在执行frame动画的时候怎么响应触发事件?
- git 远程版本库,github提供服务原理,git自动更新发送邮件
- 无良悠百佳 专坑加盟商
- maven修改默认目录结构(sourceDirectory/resources)