添加自定义传输协议编解码

This commit is contained in:
ranchuan
2024-03-20 10:28:45 +08:00
parent 5bd29dd25d
commit 08bdc1ddaa
5 changed files with 198 additions and 2 deletions

View File

@@ -131,5 +131,7 @@
2024.1.15 2024.1.15
实现方案导入导出,根据选项自动生成文件名 实现方案导入导出,根据选项自动生成文件名
添加任务时添加对应的错误码 添加任务时添加对应的错误码
2024.3.20
添加自定义传输协议编解码

View File

@@ -500,7 +500,7 @@ if __name__ == "__main__":
# data=bytearray([2,1,2,3,0, 3,5,6,7,0, 9,8,9,10,0]) # data=bytearray([2,1,2,3,0, 3,5,6,7,0, 9,8,9,10,0])
u.cmd=0x50 u.cmd=0x50
data=bytearray([7]) data=bytearray([6])
print(u.encode(data).hex(' ')) print(u.encode(data).hex(' '))
# with open("file/EX_Coder_Test_2023-07-6.json","rb") as f: # with open("file/EX_Coder_Test_2023-07-6.json","rb") as f:
@@ -538,7 +538,7 @@ if __name__ == "__main__":
# 总线设置20V # 总线设置20V
# 59 6d 06 00 50 00 00 05 c8 00 8b b0 # 59 6d 06 00 50 00 00 05 c8 00 8b b0
# 关总线 # 关总线
# 59 6D 43 05 00 50 00 00 00 06 0E 0E # 59 6d 04 00 50 00 00 06 90 9d
# 检总线电流 # 检总线电流
# 59 6d 04 00 50 00 00 07 51 5d # 59 6d 04 00 50 00 00 07 51 5d

View File

@@ -118,6 +118,15 @@ class sql:
print(i) print(i)
return a return a
# 下载文件数据
def download_data(self,table_name:str,id:int):
cmd="select name,data from {d1} WHERE id={d2};".format(d1=table_name,d2=id)
self.cur.execute(cmd)
a=self.cur.fetchall()[0]
name=a[0].replace('\\','/').split('/')[-1].split('.')
name='.'.join(name[:-1])+'--'+str(id)+'.'+name[-1]
return (name,a[1])
# 下载指定文件,返回文件路径 # 下载指定文件,返回文件路径
def download(self,id:int): def download(self,id:int):
if not os.path.exists(self.download_path): if not os.path.exists(self.download_path):

82
mysql/prot_cmd.py Normal file
View File

@@ -0,0 +1,82 @@
import json
import mysql as sql
import prot_codec as pr
SQL=sql.sql()
SQL.init("test_data")
_DATA=None
# 获取文件夹目录,参数:无
def get_dirs_list():
r=SQL.show_tables()
j=[]
for item in r:
j.append(item[0])
js=json.dumps(j)
return js
# 获取文件列表参数json{文件的目录}
def get_files_list(j:bytearray):
SQL.table_name=json.loads(j)["dir"]
r=SQL.show()
js=json.dumps(r)
print(js)
return js
# 获取文件参数json{文件目录,文件序号}
def get_file_data(j:bytearray):
js=json.loads(j)
name,data=SQL.download_data(js["dir"],js["id"])
print(name,len(data))
global _DATA
_DATA=data
js=json.dumps({'name':name,"size":len(data)})
return js
# 获取指定长度的数据,参数json{偏移,长度}
def get_data(j:bytearray):
js=json.loads(j)
off=js["off"]
length=js["len"]
if(off<len(_DATA)):
data=_DATA[off:]
if(length<len(data)):
return data[:length]
else:
return data
return bytearray()
_cmd_list={
"get_dirs":get_dirs_list,
"get_files":get_files_list,
"get_file":get_file_data,
"get_data":get_data,
}
if __name__ == '__main__':
# dirs_str=get_dirs()
# data=pr.encode(b"dirs",dirs_str.encode("utf-8"))
# print(data.hex(' '))
# print(pr.decode(data))
# files=_cmd_list["get_files"](b"checker_host_app")
# print(json.loads(files))
# print(list(_cmd_list.keys()))
data=_cmd_list["get_file"](json.dumps({"dir":"checker_host_app","id":42}))
print(data)
ret=bytearray()
off=0
while off<len(_DATA):
ret+=_cmd_list["get_data"](json.dumps({"off":off,"len":200}))
off+=200
if(ret==_DATA):
print("check success")
else:
print("check failed")

103
mysql/prot_codec.py Normal file
View File

@@ -0,0 +1,103 @@
import os
import sys
# 计算整个数据流的CRC
def _crc16(data:bytearray):
lenth=len(data)
if(lenth>0):
crc=0xffff
for i in range(lenth):
crc=(crc^data[i])&0xffff
for j in range(8):
if(crc&1)!=0:
crc=((crc>>1)^0xa001)&0xffff
else:
crc=(crc>>1)&0xffff
return bytearray([crc&0xff,(crc>>8)&0xff])
return bytearray([0,0])
# 0xff帧起始0xfe帧结尾
# 0xf0转义标识
# 0xf1命令数据分割
# 0xf2数据校验分割
# 字节数据大于等于0xf0 之后要转义
def _tran(data:bytearray):
ret=bytearray()
for item in data:
if(item>=0xf0):
ret.append(0xf0)
ret.append(item-0xf0)
else:
ret.append(item)
return ret
# 去转义
def _untran(data:bytearray):
ret=bytearray()
i=0
length=len(data)
while i<length:
if(data[i]>=0xf0):
ret.append(data[i]+data[i+1])
i+=1
else:
ret.append(data[i])
i+=1
return ret
# 以命令和数据编码
def encode(cmd:bytearray,data:bytearray):
crc=_crc16(cmd+data)
ret=bytearray()
ret.append(0xff)
ret+=_tran(cmd)
ret.append(0xf1)
ret+=_tran(data)
ret.append(0xf2)
ret+=_tran(crc)
ret.append(0xfe)
return ret
# 解码为命令和数据
def decode(data:bytearray):
while len(data)>0:
if(data[0]!=0xff):
data=data[1:]
else:
break
if(len(data)==0):
return (None,None)
if(data[0]==0xff and data[-1]==0xfe):
data=data[1:-1]
cmd_index=data.find(0xf1)
data_index=data.find(0xf2)
cmd=_untran(data[:cmd_index])
da=_untran(data[cmd_index+1:data_index])
crc=_untran(data[data_index+1:])
if(crc==_crc16(cmd+da)):
return (cmd,da)
return (None,None)
if __name__ == "__main__":
data=encode(b"cmd_test",bytearray([0xff,0xfd,0xff,0xde,0xde]))
print(data.hex(' '))
print(decode(data))