确保 StreamReader 一次处理一条消息
Ensure StreamReader handles one message at a time
我正在使用 aioisotp library,有时收到的消息靠得很近。这意味着 aioisotp 有时可以提供 2 条组合在一起的消息。
例如,
03 7F 36 78 00 00 00 00
02 76 02 00 00 00 00 00
我收到这 2 条消息,相隔 <2 毫秒。 aioisotp
returns 将其合并为一条消息:7f36787602
我认为正在发生的事情:
StreamReader.feed_data()
正在接收第一条消息 (7F3678) 并添加到缓冲区。
- 然后它会标记
read()
使用 _wakeup_waiter()
使用数据,这会在 future()
上设置结果
- 在可以安排
read()
消费数据之前,收到第二条消息(7602); StreamReader.feed_data()
被调用,缓冲区被 扩展 新数据。因此,缓冲区现在包含 7F36787602。
read()
现在发生,两条数据一起接收。
收到的数据中没有任何信息告诉我这是 >1 条消息,因此我需要确保一个 feed_data()
后跟 read()
.
的顺序
作为测试,在 StreamReader.feed_data()
中我将 self._buffer.extend(data)
更改为 self._buffer=bytearray(data)
虽然这行得通,但感觉这不是正确的处理方式。确保 read()
一次只收到一条消息的正确方法是什么?
StreamReader
需要 streaming 数据,例如来自 TCP/IP 套接字或管道的数据。这样的数据没有“消息”的概念,只有字节流。即使对等方以单独的突发发送字节,这些字节也可能被发送方或接收方的 OS 或它们之间的网络设备合并或拆分。在一般情况下,对 feed_data
或 asyncio 的其他部分进行任何更改都无法解决此问题。
如果您需要通过 TCP 流发送单独的消息,则需要添加显式 framing。例如,您可以在消息前面加上消息长度,或者您可以在两条消息之间插入一个不能出现在消息中的分隔符。有关前者的示例,请参阅 。
我正在使用 aioisotp library,有时收到的消息靠得很近。这意味着 aioisotp 有时可以提供 2 条组合在一起的消息。 例如,
03 7F 36 78 00 00 00 00
02 76 02 00 00 00 00 00
我收到这 2 条消息,相隔 <2 毫秒。 aioisotp
returns 将其合并为一条消息:7f36787602
我认为正在发生的事情:
StreamReader.feed_data()
正在接收第一条消息 (7F3678) 并添加到缓冲区。- 然后它会标记
read()
使用_wakeup_waiter()
使用数据,这会在future()
上设置结果
- 在可以安排
read()
消费数据之前,收到第二条消息(7602);StreamReader.feed_data()
被调用,缓冲区被 扩展 新数据。因此,缓冲区现在包含 7F36787602。 read()
现在发生,两条数据一起接收。
收到的数据中没有任何信息告诉我这是 >1 条消息,因此我需要确保一个 feed_data()
后跟 read()
.
作为测试,在 StreamReader.feed_data()
中我将 self._buffer.extend(data)
更改为 self._buffer=bytearray(data)
虽然这行得通,但感觉这不是正确的处理方式。确保 read()
一次只收到一条消息的正确方法是什么?
StreamReader
需要 streaming 数据,例如来自 TCP/IP 套接字或管道的数据。这样的数据没有“消息”的概念,只有字节流。即使对等方以单独的突发发送字节,这些字节也可能被发送方或接收方的 OS 或它们之间的网络设备合并或拆分。在一般情况下,对 feed_data
或 asyncio 的其他部分进行任何更改都无法解决此问题。
如果您需要通过 TCP 流发送单独的消息,则需要添加显式 framing。例如,您可以在消息前面加上消息长度,或者您可以在两条消息之间插入一个不能出现在消息中的分隔符。有关前者的示例,请参阅