Почему в библиотеке сокетов python не включен метод recvall(), например sendall()?

При использовании метода recv() иногда мы не можем получать столько данных, сколько хотим, так же, как и с помощью send(). Но мы можем использовать sendall() для решения проблемы отправки данных, как получить данные? Почему такого метода recvall() нет?

Ответ 1

Нет фундаментальной причины, почему такая функция не может быть предоставлена ​​как часть стандартной библиотеки. Фактически, была хотя бы одна попытка добавить recvall().

Учитывая, что его можно легко реализовать как цикл вокруг recv(), я не думаю, что это серьезное упущение.

Ответ 2

send содержит дополнительную информацию, которая recv не содержит: сколько данных необходимо отправить. Если у вас есть 100 байт данных для отправки, sendall может объективно определить, было ли отправлено менее 100 байт первым вызовом send, и постоянно отправлять данные до тех пор, пока не будут отправлены все 100 байтов.

Когда вы пытаетесь читать 1024 байта, но возвращаете только 512, у вас нет способа узнать, связано ли это с тем, что остальные 512 байтов задерживаются, и вы должны попытаться прочитать больше, или если читать только 521 байт в первую очередь. Вы никогда не сможете сказать, что будет больше данных для чтения, а рендеринг recvall бессмыслен. Самое большее, что вы можете сделать, это решить, как долго вы готовы ждать (время ожидания) и сколько раз вы готовы повторить попытку, прежде чем отказаться.

Вы можете задаться вопросом, почему существует очевидная разница между чтением из файла и чтением из сокета. С файлом у вас есть дополнительная информация из файловой системы о том, сколько данных находится в файле, поэтому вы надежно различаете EOF и некоторые другие, которые могут помешать вам просмотреть доступные данные. Нет такого источника метаданных для сокетов.

Ответ 3

Потому что recvall в корне запутанно: ваше предположение состояло в том, что он читал бы точно-N байтов, но я бы подумал, что он полностью исчерпает поток, основанный на имени.

Операция, которая полностью исчерпывает поток, представляет собой опасный API для множества причин, а двусмысленность в именовании делает этот довольно непроизводительный API.