基于Python写Socket/Serial收发数据的解包
在收发tcp/ip 或是 com的时候,可能会出现粘包的情况,此时需要解包,代码入下:
def unpack(datas,header,frame_len):
'''
根据帧头和长度解包
datas 总数据包
header 帧头部信息 bytes
frame_len 需要解包的帧长
'''
if len(header) > len(datas):
return None
header_len = len(header)
search_count = 0
locate_list_idx = []
msg = None
for index,item in enumerate(datas):
if item == header[0]:
if index + frame_len <= len(datas):
locate_list_idx.append(index)
if len(locate_list_idx) == 0:
return None
for find_idx in locate_list_idx:
search_count = 1
for looptimes in range(1,header_len):
if datas[find_idx + looptimes] == header[looptimes]:
search_count += 1
if search_count == header_len:
msg = datas[find_idx:find_idx + frame_len]
print("解包数据:",msg)
for idx in range((find_idx + frame_len)-1,find_idx-1,-1):
del datas[idx]
return msg
else:
break
return msg
测试代码:
test_data = [0x55,0xaa,0x01,0x00,0x00,0x00,
0x55,0xaa,0x01,0x00,0x00,0x00,
0xff,0x0b,0xf1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0xaa,0x01,0x00,0x00,
0x55,0xaa,0x01,0x00,0x00,0x00,
0x55,0xaa,0x01,0x00,0x00,0x00,
0xff,0x0b,0xf1,0x01,0x00,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x00,0x00
]
s = time.time()
while True:
msg1 = unpack(test_data,[0x55,0xaa],6)
msg2 = unpack(test_data,[0xff,0x0b,0xf1],14)
if msg1 == None and msg2 == None:
print(time.time() - s )
break
结果:
解包数据: [85, 170, 1, 0, 0, 0]
解包数据: [255, 11, 241, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
解包数据: [85, 170, 1, 0, 0, 0]
解包数据: [255, 11, 241, 1, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0]
解包数据: [85, 170, 1, 0, 0, 85]
解包数据: [85, 170, 1, 0, 0, 0]
剩余数据: [170, 1, 0, 0, 0]
0.0009965896606445312