【问题标题】:Asyncio and pyzmq - 'utf-8' codec can't decode byte 0xff in position 0Asyncio 和 pyzmq - 'utf-8' 编解码器无法解码位置 0 中的字节 0xff
【发布时间】:2018-01-29 00:38:47
【问题描述】:

我有一个asyncio server,这是TCP Doc 中的一个示例。但是我使用pyzmq 连接到它,当服务器上的阅读器尝试阅读时,我得到一个解码错误。任何提示都非常感谢。我已经尝试过先编码为 utf-8,没有帮助。

服务器:(Python 3.6)

import asyncio

async def handle_echo(reader, writer):
    data = await reader.read(100)
    print(data)
    message = data.decode()


loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 5555, loop=loop)
server = loop.run_until_complete(coro)
loop.run_forever()

客户端:(Python 2.7)

import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect ("tcp://localhost:%s" % 5555)
socket.send("test")

完整跟踪:

    future: <Task finished coro=<handle_echo() done, defined at "E:\Projects\AsyncIOserver.py:3> exception=UnicodeDecodeError('utf-8', b'\xff\x00\x00\x00\x00\x00\x00\x00\x01\x7f', 0, 1, 'invalid start byte')>
Traceback (most recent call last):
  File "E:\Projects\AsyncIOserver.py", line 6, in handle_echo
    message = data.decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

【问题讨论】:

  • 哦,不,你是对的......它适用于 'utf-16' 但怎么会呢?顺便说一句,感谢您的快速响应。
  • 当我解码 utf-16 时,它看起来像垃圾。

标签: python utf-8 python-asyncio pyzmq


【解决方案1】:

Zeromq 使用ZMTP protocol。它是一个二进制协议,因此您将无法直接对其进行解码。

如果您对此感到好奇,请使用 wireshark 和 ZMTP plugin 检查 ZMTP 帧:

您可以看到您得到的字节实际上对应于问候消息签名。


为了在 asyncio 中接收来自 ZMQ 套接字的消息,请使用像 aiozmq 这样的专用项目:

import aiozmq
import asyncio

async def main(port=5555):
    bind = "tcp://*:%s" % port
    rep = await aiozmq.create_zmq_stream(aiozmq.zmq.REP, bind=bind)
    message, = await rep.read()
    print(message.decode())
    rep.write([message])

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

【讨论】:

  • 非常感谢您的努力,我回家时会检查一下!非常感谢!
【解决方案2】:

字节 ff 是 little-endian UTF-16 BOM 的第一个字节,它在 UTF-8 流中没有位置,其中代码点开头的最大 1 位数为 4。

有关 UTF-8 编码的更多详细信息,请参阅earlier answer of mine

至于修复它,您需要接收发送的内容。这将涉及将发送端固定为 UTF-8,或将接收端固定为 UTF-16。

您可能想查看 Python 2 和 3 中字符串之间的差异,这很可能是导致您的问题的原因(请参阅here)。

【讨论】:

  • 感谢您的提示,我正在尝试通读以使其正常工作。我在想,如果我将字符串作为二进制 b"test" 发送,我应该能够在 python3 中对其进行解码,但似乎不能开箱即用。
  • 嗯,这很奇怪,只是为了修剪错误源,我现在同时使用客户端/服务器 python3 并使用来自 pyzmq 的 send_string。收到相同的错误消息。
  • 看来ff字节毕竟与UTF-16 BOM无关。
猜你喜欢
  • 2019-05-07
  • 2021-12-01
  • 2016-05-13
  • 2023-04-02
  • 2017-07-09
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多