自定协议,串口数据处理粘包方法 最后更新时间:2026年03月06日 ### 问题 处理串口数据过程中,当前后有连续的数据的情况下,很有可能出现数据粘包的情况。 如需要的数据是`ef0001`和`de002`但是数据传输和接收过快产生粘包得到数据`ef0001de00` ### 处理思路(自定协议) 再数据包前增加1位或者2位的数据长度帧,通过先获取长度帧判断需要取的数据位。 #### 参考代码 ```python from .FingerProtocol import * import serial import time from ._Types import * from colorama import Fore, Style __all__ = [ "FingerManager", ] class FingerManager: def __init__(self,serial_conn:serial.Serial) -> None: self.serial_conn = serial_conn def send_cmd(self, packet): """发送命令包""" self.serial_conn.write(packet) self.serial_conn.flush() def read_packet(self,timeout=2): """ 读取一个完整的数据包 1. 读取包头9字节 (Header+Addr+ID+Len) 2. 解析包长度 (大端) 3. 读取剩余数据 (Len指定长度) 1. 检查是否超时 2. 读取数据 3. 检查是否完整 """ data = b'' start_time = time.time() # 1. 读取包头9字节 (Header+Addr+ID+Len) while len(data) < 9: if time.time() - start_time > timeout: return None if self.serial_conn.in_waiting > 0: data += self.serial_conn.read(min(9 - len(data), self.serial_conn.in_waiting)) else: time.sleep(0.001) # 2. 解析包长度 (大端) pkg_len = (data[7] << 8) | data[8] # 3. 读取剩余数据 (Len指定长度) total_len = 9 + pkg_len while len(data) < total_len: if time.time() - start_time > timeout: return None if self.serial_conn.in_waiting > 0: data += self.serial_conn.read(min(total_len - len(data), self.serial_conn.in_waiting)) else: time.sleep(0.001) return data ```
Comments | NOTHING