recv () данные неизвестного размера с сокетами Беркли - PullRequest
1 голос
/ 16 октября 2011

У меня есть код на C ++, в котором я использую recv () из сокетов Беркли для получения данных с удаленного хоста. Проблема в том, что я не знаю размер данных (который является переменным), поэтому мне нужен какой-то тайм-аут (вероятно), чтобы эта работа работала.

Поскольку я новичок в программировании сокетов, мне было интересно, как, например, веб-клиент обрабатывает ответы от сервера (например, сервер отправляет HTML-данные клиенту). Использует ли он какое-то время ожидания, так как не знает, насколько велика страница? То же самое с FTP-клиентом.

1 Ответ

4 голосов
/ 16 октября 2011

Если ваши данные имеют переменную длину, то обычно эти данные помещаются в другой контейнер. То есть заголовок, предшествующий фактическому блоку данных, сообщает получателю, сколько данных он должен принять.

Например, HTTP использует символы новой строки для разделения данных. Если есть сообщение переменной длины, то в заголовке оно будет включать поле «Content-length:», которое точно указывает, сколько байтов нужно прочитать после получения всего заголовка (заголовок останавливается, когда вы читаете 2 последовательные новые строки).

Прекрасно прочитать 4 байта из сокета, получить, сколько данных следует, затем выполнить другой прием и прочитать остальные. Только будьте осторожны, когда вы запрашиваете 4 байта, сокет может дать вам где-то от 1 до 4 байтов, поэтому любое значение меньше 4 означает, что вам нужно вернуться назад и запросить оставшиеся несколько байтов. Это очень распространенная ошибка. В среде разработки вы почти всегда получаете 4 байта при запросе 4, но как только вы развернете свое приложение, где-то на каком-то компьютере вы получите случайные сбои, потому что их поведение в сети несколько отличается.

Как правило, неверно использовать тайм-ауты, чтобы определить, когда вы достигнете конца данных. С тайм-аутом вы можете заставить вещи «надежно» работать в хорошо контролируемой среде разработчиков, но это очень нестабильное решение. Любой сбой процессора / диска / сети может привести к преждевременному прекращению приема приложения. Вы также ограничиваете пропускную способность и скорость отклика данных, поскольку ваше приложение спит в течение некоторого промежутка времени вместо выполнения работы.

...