从asyncio StreamReader读取

jdo*_*ner 5 python http python-asyncio server

我正在尝试扩展使用流式读取器/写入器(代码)的python asyncio HTTP服务器示例。如果我理解正确,示例处理程序将从读取器读取100个字节,并将其通过写入器回显给客户端。我正在尝试读取100个字节以上的内容...读取直到没有更多内容可读取为止。

我尝试让read()函数尽可能多地读取,

data = yield from reader.read()
Run Code Online (Sandbox Code Playgroud)

但这似乎永远无法实现。因此,我尝试读取块,直到达到EOF,

while not reader.at_eof():
    data += yield from reader.read(100)
Run Code Online (Sandbox Code Playgroud)

尽管这会检索更多数据,但似乎在读取调用时阻塞,而不是退出while循环。

如何使用流阅读器从客户端获取整个消息?

Jas*_*ohi 5

您应该检查是否StreamReader.read返回一个空字节对象来发出 EOF 信号:

data = bytearray()
while True:
    chunk = yield from reader.read(100)
    if not chunk:
        break
    data += chunk
Run Code Online (Sandbox Code Playgroud)

另外,aiohttp如果您需要功能齐全的 HTTP 客户端,请考虑使用。

  • 我只是想指出您的代码挂起的原因是您没有正确确定请求长度(或 EOF)。例如,在“HTTP/1.1”中,连接默认为“keep-alive”,因此每个连接可以有多个请求。要确定请求何时结束,您必须查看“Content-Length”标头或请求是否已分块。还有许多其他注意事项,因此如果您想使用 asyncio 从头开始​​执行此操作,我建议您阅读 HTTP RFC。另外,您链接到的示例是关于 *TCP* 回显服务器,而不是 *HTTP* 服务器。 (2认同)