2016-02-04 70 views
3

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

我试图让read()函数读取尽可能多的,

data = yield from reader.read() 

,但似乎永远阻止。所以,我想读块,直到达到EOF,

while not reader.at_eof(): 
    data += yield from reader.read(100) 

,虽然这检索更多的数据,它似乎在读呼叫阻塞退出while循环代替。

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

回答

0

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

data = bytearray() 
while True: 
    chunk = yield from reader.read(100) 
    if not chunk: 
     break 
    data += chunk 

而且,考虑使用aiohttp如果你需要一个功能齐全的HTTP客户端。

+0

我也尝试过,但没有成功。谢谢。 – jdowner

+0

你正在发送HTTP/1.1或HTTP/1.0请求/响应吗?你能发布一个完整的例子吗? –

+0

所以我对asyncio实现进行了一些探索,似乎在流中调用read()并不是这种情况下的方式,因为除非客户端主动关闭连接,否则EOF永远不会被注入到流中。你提供的例子基本上是asyncio试图自己做的,但问题是来自HTTP请求的数据包含带有b'\ r \ n'形式的行尾的字节,所以'if not chunk'条件是从来没有真实的,即使数据只有行结束。 – jdowner

-1

在at_eof之前使用feed_eof。

request_text = b'' 
while True: 
    request_text += yield from self.reader.read(1024) 
    self.reader.feed_eof() 
    if self.reader.at_eof(): 
     break 
+0

也许我不明白,但是这不是假设读者已经在feed_eof函数被调用之前收到了所有的数据吗? – jdowner

+0

查看文档https://docs.python.org/3/library/asyncio-stream.html#asyncio.StreamReader.at_eof “如果缓冲区为空且调用了feed_eof(),则返回True。” –

+0

看到这个例子https://github.com/carlosmaniero/asyncio_server/blob/master/server.py在线80. –

0

像这样:

empty_bytes = b'' 
result = empty_bytes 

while True: 
    chunk = await response.content.read(8) 

    if chunk == empty_bytes: 
     break 

    result += chunk 

要确定EOF使用

if chunk == empty_bytes: 

if not chunk: 

代替请参阅该文档(aiohttp):在返回空字节字符串

b'' 

EOF上,所以明确检查。

注:如果你想读,直到块的结束,因为它是从服务器传送,结账

StreamReader.readchunk() 

(没有测试,虽然)