使用 pySerial 读取完整的二进制消息
Read complete binary message using pySerial
我正在尝试使用 pySerial 将二进制数据从一个串行端口重定向到数据库。
问题是 pySerial 只允许读取带有 serial.read()
的单个字符和整行,直到带有 serial.readline
的 EOL 字符。但是,使用的协议 (RTCMv3) 是二进制的,消息的长度各不相同,这意味着 readline 不起作用,read 只会给我一个字节序列。我想要实现的是区分各个消息。
我用 socat 也试过同样的方法。 Socat 以某种方式能够在不知道协议结构本身的情况下找出单个消息的长度:
socat -u -x /dev/ttyUSB2,raw -
> 2018/03/15 21:04:24.394224 length=171 from=9 to=179 d3 00 a5 3e c0 00 72
7d b1 40 a0 3c 26 c5 91 fc fc 9f d3 30 f0 07 7f 82 27 fd 82 [...] 9f f0 f8
是否有与 Python/pySerial 类似的实现方式?
我认为您正在寻找 serial.readline()
或
serial.read_until()
方法:
https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.readline
https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read_until
两者都允许可变长度消息,只要找到相同的结束分隔符即可。两者都很好,但换行符偶尔会成为正在传输的二进制数据的正常部分,这给 serial.readline()
带来了困难。如果您可以检测到消息帧的结束字符或定界符,那么 serial.read_until()
将很有用。
使用像 COBS 这样保证删除分隔符(零字节,b'\x00'
)的编码方法将有助于找到每条消息的结尾。如果您无法更改发送协议,您可能需要搜索它使用的分隔符和数据包结构。
我正在尝试使用 pySerial 将二进制数据从一个串行端口重定向到数据库。
问题是 pySerial 只允许读取带有 serial.read()
的单个字符和整行,直到带有 serial.readline
的 EOL 字符。但是,使用的协议 (RTCMv3) 是二进制的,消息的长度各不相同,这意味着 readline 不起作用,read 只会给我一个字节序列。我想要实现的是区分各个消息。
我用 socat 也试过同样的方法。 Socat 以某种方式能够在不知道协议结构本身的情况下找出单个消息的长度:
socat -u -x /dev/ttyUSB2,raw -
> 2018/03/15 21:04:24.394224 length=171 from=9 to=179 d3 00 a5 3e c0 00 72
7d b1 40 a0 3c 26 c5 91 fc fc 9f d3 30 f0 07 7f 82 27 fd 82 [...] 9f f0 f8
是否有与 Python/pySerial 类似的实现方式?
我认为您正在寻找 serial.readline()
或
serial.read_until()
方法:
https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.readline
https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read_until
两者都允许可变长度消息,只要找到相同的结束分隔符即可。两者都很好,但换行符偶尔会成为正在传输的二进制数据的正常部分,这给 serial.readline()
带来了困难。如果您可以检测到消息帧的结束字符或定界符,那么 serial.read_until()
将很有用。
使用像 COBS 这样保证删除分隔符(零字节,b'\x00'
)的编码方法将有助于找到每条消息的结尾。如果您无法更改发送协议,您可能需要搜索它使用的分隔符和数据包结构。