Почему asyncio.StreamReader.read return не блокирует поток? - PullRequest
0 голосов
/ 05 ноября 2019

Я пытался запустить этот пример 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 голосов
/ 05 ноября 2019

Я не отправлял EOF на стороне клиента, так почему функция чтения не заблокирована?

Поскольку некоторые данные были получены, а read предоставил их. В документации, которую вы указали, явно сказано, что read(n) читает " до n байт". Это особенность: если read(n) возвращается только тогда, когда доступны полные n байтов, это приведет к bufferbloat на эхо-сервере, который ничего не будет отображать до тех пор, пока не будет прочитано полное количество. семантика, единственный способ иметь эхо-сервер без задержки, вызванной буфером, - это читать данные побайтно с read(1), что было бы ужасно неэффективно.

Предполагаемое значение read(n), котороеэхо-сервер использует: «Дайте мне данные, как только они станут доступны, но не более n байт за раз». Ограничение должно быть предоставлено не потому, что оно обязательно имеет смысл, а просто для того, чтобы не допустить, чтобы мошеннический одноранговый узел заполнил вашу память, отправив большое количество данных.

Обратите внимание, что с таким read(), указанным так, легкоопределить другую функцию, которая считывает данные до тех пор, пока не станет доступна сумма точная ;на самом деле такой метод для StreamReader уже существует: readexactly.

Означает ли это, что Bytearray содержит EOF после string.encode?

A bytes объект (который отличается от bytearray object), возвращаемый read, никогда не "содержит EOF", потому что EOF не символ, это условие, которое было передано-of-группа. В StreamReader API условие EOF обозначается read, возвращающим пустой объект байтов.

...