Не целые страницы

Автор mihail_1, 14 января 2014, 10:30:49

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

mihail_1

Получаю по HTTP через сокет содержимое страниц отдаваемое серверами. В отдельных случаях приходит только часть страницы. Сообщений об Ошибках при этом не бывает. Сервера не всегда передают в заголовке длинну страницы. Как проверять что страница пришла не вся?

endru

Можно по подробней, каким образом вы получаете страницу (браузер, скрипты и т.д.) и более подробно.
И, если не коммерческая тайна, каким серверам отправляете запросы?

mihail_1

Программа на Си.
connect(...);
send(...);
цикл recv(...) пока >0
если 0 корректное завершение, если <0 - ошибка

К разным серверам (сейчас в базе около 100000 адресов сайтов)

endru

Проверять сохранные данные? всегда же последним передается тег </html>

И если на странице есть сторонние ресурсы, то придется учить вашу программу запрашивать такие данные.

mihail_1

Тег </html> может быть не в конце документа, а может и вообще отсутствовать, это ни как не повлияет на отображение страниц в браузерах, но вроде бы бразеры как-то определяют, если страница загружена не вся.

endru

#5
mihail_1, данные в браузере отображаются по мере загрузки html тегов.
Весь контент (картинки к примеру) идут отдельными параллельными запросами браузера к серверу или серверам, смотря куда ведут ссылки в тегах <img> (опять же картинки в пример).
Загрузка продолжается, пока не загрузится весь контент или не сработает timeout на соединение.
</html> всего лишь указывает на логический конец тегов на странице (вам нужно больше?  :) )

Эксперименты

1. проверьте проблемные сервера на примере(жирным выделено что нужно вводить в терминале)
telnet debianforum.ru 80
Trying 5.187.3.236...
Connected to debianforum.ru.
Escape character is '^]'.
GET / HTTP/1.1  //вводим руками или копируем
Host: debianforum.ru  //вводим руками или копируем и нажимаем 2 раза Enter. результат внизу экрана)

2. Иногда сервера в заголовках передают Content-Length указывает на количество байт тела страницы.
А иногда указывается в виде 16-ного числа непосредственно перед телом страницы:

[свернуть]

mihail_1

Для браузера тег html лишь контейнер для которого могут быть прописаны стили, но никак не начало/конец отображаемого документа. Поэтому наличие в конце документа или где-то в документе </html> не гарантирует что документ загрузился весь. Его отсутствие не гарантирует, что документ загрузился не полностью.

Моя программа не является браузером и не запрашивает картинки вместе с кодом страницы. В баузерах я давно не видел после завершения загрузки неполные страницы.

Случаи timeout и другие ошибки отслеживаются. Прием неполного документа, так же как и полного завершается, когда recv(...) возвращает первый 0, после одного или нескольких положительных значений. (используется блокирующий режим)

endru

mihail_1, не спорю, теги не обязательны. было предложено как вариант  :)
что насчет 2 пункта под спойлером?

mihail_1

Content-Length многие сервера не передают, поэтому тоже ненадежный способ, а второй вариант передачи вижу вообще впервые.

Telnet для ручной проверки я пытался использовать, но потери нестабильны и поймать их руками не удается. Сервера здесь не виноваты, потери пакетов происходят на магистральных каналах (но чем дальше до сервера тем выше вероятность потери).
Странно, что TCP, который в отличии от UDP должен предотвращать эти потери, на практике ни чем не помогает. Или он просто не сообщает о потерях протоколам которые над ним?


mihail_1

Тогда в заголовке должно быть
Transfer-Encoding: chunked
а этого нет.

endru

mihail_1, хм... очень странно! можете кинуть сервер для примера я его помучаю скриптами  :)

mihail_1

Например zonakz.net, но это до меня от него канал плохой (около 1% битых страниц), а до Вас может быть и все хорошо.