使用序列化 python 中的对象以与 XBee 一起使用

Using serializing an object in python for use with an XBee

对于我正在进行的项目,我应该使用 XBee 无线电模块,这不是非常重要,除了我必须读取和写入它们的串行端口才能使用它们。我目前正在使用 Python 和 ROS,因此我正在尝试通过 XBees 发送 TransformStamped 消息。

我的问题是,除非我误解了 Serial.read() 和 Serial.write() 的工作原理,否则我怎么知道要读取多少字节?我正计划使用 Pickle 将数据序列化为一个字符串,然后通过串口发送。有没有更好的方法被我忽略了?是否有某种循环可以读取数据直到读取腌制字符串的末尾?

简短的回答是,serial.read() 无法告诉您要读取多少字节。要么您对消息的长度有一些先验知识,要么您发送的数据具有某种表示消息之间边界的方法。

提示;知道消息有多长是不够的,您还需要知道消息实际开始在接收到的字节流中的位置。您不确定接收到的字节是否与发送的字节完全对齐:您可能没有在发送器之前启动接收器,因此它们可能不同步。

任何序列化都必须要问,它是自定界的,还是不是? Google 协议缓冲区不是。我认为 Pickle 也不是。 ASN.1 BER 至少在某种程度上是。 XML.

也是

关键是 XBee 模块(假设您使用的是来自 Digi 的模块)只是不可靠的字节传输,因此无论您通过它们输入什么都必须以某种方式分隔,以便接收端知道它何时有一条完整的消息。因此,如果你 pickle 或 Google Protocol Buf 你的消息,你需要一些其他方式来构建序列化数据,以便接收端知道它有一个完整的消息(即它看到开头 and结束)。这可以像一些字节模式(例如 0xffaaccee00112233)一样简单,用于表示一个消息的结尾和下一个消息的开始,选择它们不太可能出现在发送的消息本身中。您在接收端的代码将读取并丢弃数据,直到看到该模式,然后将后续数据读入缓冲区,直到再次看到该模式,然后才会尝试将数据 de-pickle/de-GPB 放回一个东西。

使用 ASN.1 BER,数据流本身有效地包含相同的东西,从而节省您的精力。它使用标签、值和长度字段来告知其解码器有关传入数据的信息,如果与原始模式相比传入数据对解码器没有意义,则很容易忽略不正确的帧数据。

这种问题也存在于 tcp 套接字上,尽管至少在这些套接字上或多或少地保证了交付(您收到的第一个字节是第一个发送的字节)。 Digimesh 连接并没有完全达到与 tcp 套接字相同的保证交付级别,因此接收应用程序需要其他一些东西(如帧字节模式)才能知道它与发送方同步。