Вы можете запросить этот блок recv, пока не будут получены все данные, с флагом MSG_WAITALL
.Однако, если поступает сигнал, системный вызов, который выполнил некоторую работу (т.е. принимает часть данных), не может быть автоматически перезапущен для получения остальных.Таким образом, даже с MSG_WAITALL
существуют случаи, когда вызов recv может вернуться до того, как буфер заполнится, и вы должны быть готовы обработать эти случаи.Учитывая это, многие люди просто выбирают циклы и не беспокоятся о малоизвестных флагах, таких как MSG_WAITALL
.
Что касается того, почему это так по умолчанию, на ум приходит несколько причин:
- Часто вы хотите, чтобы получил частичное чтение.Например, если вы постепенно отображаете данные по мере их поступления, или если вы передаете их в другое место, или если данные настолько велики, что вы не можете буферизовать все это в памяти сразу.В конце концов, если вы просто немедленно записываете в файл, вы заботитесь о том, чтобы разделить его на 200 записей, а не, скажем, на 150?
- Иногда вы даже не знаете, сколько данных вам нужноначало.Рассмотрим протокол
telnet
, который был популярен во времена разработки API сокетов BSD.Обычно вы будете получать несколько байтов за раз, нет полей длины, указывающих, сколько данных ожидать, и, кроме того, вам нужно отобразить эти данные сразу .Блокировать не имеет смысла, пока вы не заполните здесь буфер.Аналогично с линейно-ориентированными протоколами, такими как SMTP или IMAP - вы не знаете, сколько длится команда, пока вы не получите ее все. recv
часто используется для сокетов дейтаграмм, где она получаетодна датаграмма, даже если она намного меньше, чем предоставленный буфер.Естественное расширение потоковых сокетов - просто возвращать столько, сколько вы можете, не дожидаясь.
Но самое главное, так как вы должны быть готовы к работе с частичным буфером в любом случае Хорошо, если вы заставляете людей разбираться с этим по умолчанию, чтобы они включали ошибки в своем цикле раньше, а не заставляли их прятаться до тех пор, пока не поступит сигнал в неудачный момент.