为什么StreamReader无法接收此代码?

时间:2018-11-02 16:55:15

标签: python-asyncio streamreader streamwriter

我对StreamReader / StreamWriter有疑问。

为简化我的实际代码,就像下面的代码(它们可以运行)一样。运行服务器后,运行客户端以请求它。服务器将不会读取任何数据

服务器代码:

import asyncio

loop = asyncio.get_event_loop()


async def log(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
    print("Wait read")
    data = await reader.read(-1)
    print("<:", data)
    writer.write(data)
    await writer.drain()
    print(">:", data)


async def link(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
    asyncio.run_coroutine_threadsafe(log(reader, writer), loop)
    print("Connect.")
    await asyncio.sleep(1)


loop.run_until_complete(
    asyncio.start_server(
        link, "0.0.0.0", 1080, loop=loop
    )
)
loop.run_forever()

客户代码:

import socket
import traceback

try:
    sock = socket.create_connection(("127.0.0.1", 1080))
    sock.sendall(b"Hello")
    print(sock.recv(1024))
    sock.close()
except socket.error:
    traceback.print_exc()

我知道如何解决此问题,但我想知道为什么会出现此问题。

1 个答案:

答案 0 :(得分:0)

根据documentation

  

StreamReader.coroutine读取(n = -1)

     

最多读取n个字节。如果未提供n或将其设置为-1,则读取直到EOF并返回所有读取的字节。

     

如果收到EOF并且内部缓冲区为空,则返回一个空字节对象。

您的程序正在等待呼叫data = await reader.read(-1)reader.read(-1)仅在收到EOF(文件末尾)时返回。换句话说,这意味着当另一端(客户端)关闭套接字时它将返回。

您可以尝试在客户端代码中对此行print(sock.recv(1024))进行注释并注释掉,您将看到data = await reader.read(-1)返回。