为什么asyncio.StreamReader.read返回没有阻止线程?

时间:2019-11-05 08:06:11

标签: python python-3.6 python-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。

  

协程读取(n = -1)最多读取n个字节。如果未提供n或设置   到-1,读取直到EOF并返回所有读取的字节。

     

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

     

这种方法是协程。

我没有在客户端发送EOF,那么为什么read函数没有被阻止? 是否表示Bytearray之后的EOF包含string.encode

1 个答案:

答案 0 :(得分:0)

  

我没有在客户端发送EOF,那么为什么读取功能没有被阻止?

因为收到了一些数据,所以read提供了它。您明确引用的文档说read(n)读取“ 最多 n个字节”。这是一个功能:如果read(n)仅在完整的n个字节可用时才返回,它将在回显服务器中引入bufferbloat,直到读入全部量后,它才回显任何内容。语义上,拥有没有缓冲区引起的等待时间的回声服务器的唯一方法是使用read(1)逐字节读取数据,这效率极低。

回显服务器使用的read(n)的预期含义是“尽快将数据提供给我,但一次不超过 n 个字节”。必须提供限制不是因为它一定有意义,而仅仅是为了防止流氓对等体通过发送大量数据来淹没您的内存。

请注意,使用这样指定的read(),很容易定义另一个函数来读取数据,直到获得 exact 数量为止。实际上,StreamReader上的这种方法已经存在:readexactly

  

这是否意味着Bytearray在string.encode之后包含EOF?

read返回的bytes对象(与bytearray对象不同)永远不会“包含EOF”,因为EOF不是字符,这是发出信号的条件-带。在StreamReader API中,通过read返回空字节对象来表示EOF条件。