多功能电能表(DL/T645-1997)协议数据有效解析方法,谁有好的建议,烦劳高人提醒一下。 ( 积分: 100 )

  • 主题发起人 主题发起人 陌生
  • 开始时间 开始时间

陌生

Unregistered / Unconfirmed
GUEST, unregistred user!
最近在写一个多功能电能表通讯及协议数据解析程序的时候遇到了一些问题,想了好长时间没有想到一个好的DL/T-645-1997协议数据的解析方法。其中协议桢格式如下:
---------------------------------------------------------------------------
|桢头[1 byte]|电表地址[6 byte]|桢头[1 byte]|控制码[1 byte]|数据长度[n byte]|校验码[1 byte]|桢尾[1 byte]|

谁有好的建议,麻烦各位帮忙提醒一下,先谢谢了!!!
 
1.分段:把从桢头到桢尾从数据流中截取出来。
2.校验:通过校验判断是否合法数据。
3.解码:根据协议的内容定义一个数据结构,将合法的数据解码放在数据结构中以供使用。
 
谢谢moolleychean的关注,我现在的问题就是这样的:我现在的程序是通过TCP与终端通讯,每次终端发送一桢数据到上位机,由于数据较少,所以就省去第一步分段处理而是直接从流中读取数据到缓冲区,然后检查数据的合法性。问题在于你所说的解码的问题,我现在没有一个自己觉得很有效的方式。我现在处理方式是使用联合体数据结构的方式,数据结构大致定义如下:
TMo_Info=record
private
bHeader_1:Byte;
aAddr:Array[0..5]of Byte;
bHeader_2:Byte;
bControlCode:Byte;
bLen:Byte;
bDataFlag:Array[0..1]of Byte;
bData:Array of Byte;
bCS:Byte;
bEnd:Byte;
end;

TRecvBuf=Record
case byte of
1:aBuf:array [0..1023] of byte;
2:Mo_Info:TMo_Info;
end;

未解决的问题就是TMo_Info结构中的bData域数据长度的不确定性问题,导致不可实行?
 
我没有用过这种方式,不知道为什么要用变体记录。不过你可以将bData:Array of Byte;改为静态数组bData:Array[0..255] of Byte;反正你的bData的长度已经由bLen确定了,如果bLen不是表示bData的长度的话,那再加一个字段bDataLen: Byte;来表示bData的长度。这样你算好字节后就可以定义变体记录了。
另:我们写的类似的程序一般都是采用Record+TList来实现的。
 
楼上这样是可行的,你设置最大长度的静态数组就好。
 
再次感谢moolleychean,zywdc的关注,我使用变体记录的原因是:可以直接从数据流读取数据放到TMo_Info结构体中,代码如下:
AThread.Connection.ReadBuffer(RecvBuf, AThread.Connection.ReadFromStack());
这样如果改变bData;Array of byte数组为bData:Array[0..255] of byte 静态数组的话,就会导致后面两个字段bCS,bEnd数据读取错误。如果不使用变体记录结构的话,就需要从数据流中读取数据后逐字节转换写入到TMo_Info结构。这样一来会不会降低应用上的效率呢?我现在的方法是:不定义最后两个字段,将后面数据全部放入bData域,然后根据bLen域从bData域读取有效数据,但这样感觉上有点不太正常。
 
可以做个类来简化思路:
TMo_Info = class(TObject)
private
FRecvBuf: array[0..1023] of Byte;
public
property Datas write SetDatas;
property Header read GetHeader;
.....
end;
把接收到的数据赋给Datas,解析后的数据从属性读出。
 
谢谢nicai_wgl的关注,看来必须要有一个逐字节的数据解码过程了。不知道哪位高人有没有更好的方法,再等待一下...
 
你的协议桢经过分段和校验是正确的话,那么你的|校验码[1 byte]|桢尾[1 byte]|都可以不再考虑了,你还需要它们干什么呢,就算你需要根据收到的帧重新封装一个数据帧,校验码再算一下,帧尾是规范固定的。所以你的方法:
----------------------------------------
我现在的方法是:不定义最后两个字段,将后面数据全部放入bData域,然后根据bLen域从bData域读取有效数据,但这样感觉上有点不太正常。
----------------------------------------
我觉得是可行的。
 
多人接受答案了。
 
后退
顶部