Как я могу узнать, пуст ли после первого вызова recv буфер чтения? Если он не пустой, мне придется снова вызвать recv, но если я сделаю это, когда он пуст, я бы заблокировал его на долгое время.
Вы можете использовать select
или _ 2_ системные вызовы вместе с дескриптором вашего сокета, чтобы узнать, есть ли данные, ожидающие чтения из сокета.
Однако обычно должен существовать согласованный протокол, которому следуют отправитель и получатель, чтобы обе стороны знали, сколько данных должно быть передано. Например, возможно, отправитель сначала отправляет 2-байтовое целое число, указывающее количество отправленных байтов. Затем получатель сначала считывает это 2-байтовое целое число, чтобы знать, сколько еще байтов нужно прочитать из сокета.
В любом случае, как указал Тони ниже, надежное приложение должно использовать комбинацию информации о длине в заголовке в сочетании с опросом сокета на предмет дополнительных данных перед каждым вызовом recv
(или с использованием неблокирующего сокета). Это предотвратит блокировку вашего приложения в том случае, если, например, вы знаете (из заголовка), что все еще должно оставаться 100 байтов для чтения, но одноранговый узел не может отправить данные по какой-либо причине (возможно, одноранговый компьютер был неожиданно отключился), что привело к блокировке вашего recv
вызова.
Как я могу узнать, сколько байтов я прочитал в recv_buffer? Я не могу использовать strlen, потому что получаемое мной сообщение может содержать нулевые байты.
Системный вызов recv
вернет количество прочитанных байтов или -1, если произошла ошибка. .
На странице руководства для recv (2):
[recv] возвращает количество полученных байтов или -1, если произошла ошибка. Возвращаемое значение будет 0, когда одноранговый узел выполнил упорядоченное завершение работы.
person
Charles Salvia
schedule
06.12.2010