python - 为什么 asyncio.StreamReader.read 返回没有阻塞线程?
问题描述
这条线让我感到困惑:
data = yield from reader.read(100) # data -> b'Hello World!'
客户端向服务器发送字符串'Hello World!'
,Bytearray
长度小于 100。
coroutine read(n=-1) 最多读取 n 个字节。如果未提供 n 或设置为 -1,则读取直到 EOF 并返回所有读取字节。
如果收到 EOF 并且内部缓冲区为空,则返回一个空字节对象。
这个方法是协程。
我没有EOF
在客户端发送,那么为什么该read
功能没有被阻止?这是否意味着Bytearray
包含EOF
after string.encode
?
解决方案
我没有在客户端发送EOF,那么为什么读取功能没有被阻止?
因为收到了一些数据,并read
提供了它。您明确引用的文档说read(n)
“最多n 个字节”。这是一个特性:如果read(n)
仅在完整的 n 个字节可用时返回,它将在回显服务器中引入缓冲区膨胀,在读入全部量之前不会回显任何内容。有了这样的语义,唯一的方法就是有一个回显没有缓冲区引起的延迟的服务器将使用 逐字节读取数据read(1)
,这将是非常低效的。
回显服务器使用的预期含义read(n)
是“一旦数据可用就给我数据,但一次不超过n个字节”。必须提供限制不是因为它必然有意义,而只是为了防止流氓对等方通过发送大量数据来淹没您的内存。
请注意,通过这样的read()
指定,很容易定义另一个函数来读取数据,直到确切的数量可用;其实这样的方法就StreamReader
已经存在了:readexactly
.
这是否意味着 Bytearray 在 string.encode 之后包含 EOF?
从不“包含 EOF”返回的字节对象(与 bytearray 对象不同),因为EOF不是字符read
,它是带外信号的条件。在StreamReader
API 中,EOF 条件通过read
返回一个空字节对象来指示。
推荐阅读
- node.js - 项目太大
- php - Laravel 有 2 张桌子
- javascript - 每次调用函数时,JavaScript 都会动态重复元素
- javascript - 使用 for-in 循环查找价值时遇到问题
- ajax - 点击视频时计算观看次数
- autoit - 为什么 AutoIt 不执行点击?
- javascript - 如何操作位于状态中的数据并显示到页面?
- php-internals - php-src 文件中 `/* $Id$ */` 的功能是什么
- android - 使用 AsyncStorage 时,本机反应每 10 毫秒重新渲染一次视图
- amazon-web-services - 如何在 Amazon Linux2 上安装 docker