这一行让我感到困惑:
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
?
答案 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条件。