为什么 asyncio.StreamReader.read return 没有阻塞线程?

Why asyncio.StreamReader.read return didn't block the thread?

我尝试 运行 这个 asyncio 示例 https://docs.python.org/3.6/library/asyncio-stream.html?highlight=start_server#tcp-echo-server-using-streams

这一行让我很困惑:

data = yield from reader.read(100) # data -> b'Hello World!'

客户端向服务器发送字符串'Hello World!'Bytearray长度小于100

coroutine read(n=-1) Read up to n bytes. If n is not provided, or set to -1, read until EOF and return all read bytes.

If the EOF was received and the internal buffer is empty, return an empty bytes object.

This method is a coroutine.

我没有在客户端发送EOF,那么为什么read函数没有被阻止? 这是否意味着 Bytearraystring.encode 之后包含 EOF

I didn't send EOF in client side, So why the read function didn't blocked?

因为收到了一些数据,read 提供了它。您引用的文档明确表示 read(n) 读取“最多 n 个字节”。这是一个特性:如果 read(n) 仅在完整的 n 个字节可用时才返回,它会在回显服务器中引入 bufferbloat,在读入全部数量之前不会回显任何内容。这样语义上,没有缓冲区引起的延迟的回显服务器的唯一方法是使用 read(1) 逐字节读取数据,这将非常低效。

回显服务器使用的 read(n) 的预期含义是 "give me the data as soon as it's available, but no more than n bytes at a time"。必须提供限制并不是因为它一定有意义,而只是为了防止流氓节点通过发送大量数据来淹没您的内存。

请注意,使用这样的 read() 指定,很容易定义另一个函数来读取数据,直到 exact 数量可用;事实上,StreamReader 上已经存在这样的方法:readexactly.

Does it mean the Bytearray contains EOF after string.encode?

A bytes object (which is distinct from a bytearray 对象) read 永远不会返回 "contains EOF" 因为 EOF 不是字符,它是带外信号的条件。在 StreamReader API 中,EOF 条件由 read 返回一个空字节对象表示。