Как я могу знать, если после вызова RECV первого раза буфер чтения пуст или нет? Если он не пуст, мне придется снова вызвать recv, но если я сделаю это, когда будет пустым, я бы его блокировал на много времени.
Вы можете использовать систему select
или poll
вызовы вместе с дескриптором сокета, чтобы сказать, если есть данные, ожидая, чтобы быть прочитана из сокета.
Однако, как правило, должен быть согласованный протокол, которым следуют как отправитель, так и получатель, чтобы обе стороны знали, сколько данных необходимо передать. Например, возможно, отправитель сначала отправляет 2-байтовое целое число, указывающее количество отправленных байтов. Затем приемник сначала считывает это 2-байтовое целое число, так что он знает, сколько еще байтов считывается из сокета.
Независимо от того, как указал Тони ниже, надежное приложение должно использовать комбинацию длины информации в заголовке в сочетании с опросом сокета для дополнительных данных перед каждым вызовом до recv
(или с использованием неблокирующего сокета) , Это предотвратит блокировку вашего приложения в случае, если, например, вы знаете (из заголовка), что все еще должно оставаться 100 байтов для чтения, но одноранговый узел не может отправить данные по любой причине (возможно, одноранговый компьютер был неожиданно отключается), тем самым вызывая блокировку вашего recv
.
Как узнать, сколько байтов у меня есть , записанное в recv_buffer? Я не могу использовать strlen, потому что сообщение, которое я получаю , может содержать нулевые байты.
Системный вызов recv
будет возвращать количество прочитанных байтов или -1, если произошла ошибка.
От человека странице для RECV (2):
[RECV] возвращает количество байтов, полученных , или -1, если произошла ошибка. Возвращаемое значение будет 0, когда сверстень выполнил упорядоченное завершение .
Какова актуальность справочной страницы `read (2)` `recv (2)`? Говорят похожие вещи, но цитирование соответствующей страницы было бы лучше. – 2010-12-06 01:46:14
@Jonathan, когда тип дескриптора является сокетом, `read` совпадает с` recv`, кроме `recv` разрешает дополнительный параметр flags. Но я отредактировал свой ответ, чтобы использовать `recv`, чтобы избежать путаницы. – 2010-12-06 01:53:59
Просто nitpick re тонкая, предположительно непреднамеренная импликация: «select/poll/how message-length в заголовке» ложно предполагает, что такие заголовки разрешают проблему блокировки, где - как select/poll, неблокирующие сокеты или потоки должны использоваться в сочетании с заголовком длины сообщения или данными дозорного устройства. – 2010-12-06 02:16:36