2016-02-04 103 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() 

(沒有測試,雖然)