Преждевременный FIN, когда контент не закончился

Anonymous спросил: 13 июня 2018 в 09:56 в: sockets

Я создаю встроенный MP3-плеер, который загружает данные из сети. Мой образец файла составляет 300 МБ, примерно 5 с половиной часов воспроизведения. Устройство не имеет соответствующей ОЗУ для буферизации и постепенно "загружает" файл за эти 5,5 часов.

Приложение выполняет запрос HTTP 1.0 для получения файла с заголовком Connection: close и сервер отвечает с ответом HTTP 1.1 с правильным размером файла и заголовком Accept-range:bytes.

Общение идет хорошо, но на сервере размером около 10 МБ просто завершается соединение с FIN.

Я смотрю, как выполняются задачи браузера на ПК:

  • Chrome: выполняет запрос с заголовком Range, выглядит как значение произвольно, а затем через один и тот же сеанс сокета выполняет запрос "в диапазоне" для всего файла. Мне кажется, что это не так, как у моих MP3-плееров, но это не так.
  • Firefox: он еще проще - просто быстро загружает весь файл в RAM / на диск и воспроизводит его оттуда.
  • li>

Вопрос: как вы думаете, почему сервер не предоставляет весь контент? Слишком длительное время загрузки? Каков правильный способ для устройств, у которых нет памяти для загрузки, чтобы постепенно получать данные с веб-сервера?

Примечание:, если бы я был безответственным человеком, не глядя на стоимость реализация, я бы определенно пошел к бездумным, имитируя поведение Chrome (в качестве удаленного комментария), а затем пришлось исправить ошибки; но я ставил вопрос здесь, чтобы получить от вас все изображения (или как можно больше), чтобы выбрать лучший и полный способ иметь минимальные затраты и минимальное количество запросов об ошибках / несоблюдении.

И спасибо для того, чтобы опробовать вопрос - очень полезно вернуться сюда с просьбой о помощи и помощи другим .


1 ответ

Steffen Ullrich ответил: 13 июня 2018 в 02:27

Слишком длительное время загрузки?

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

Каков правильный способ для устройств, не имеющих памяти для загрузки, чтобы постепенно получать данные с веб-сервера?

Поскольку сервер поддерживает запросы диапазона, правильным способом является выдача нескольких запросов, в которых каждый запрос не содержит больше данных, чем вы можете хранить в ОЗУ. Конечно, следующий запрос должен быть выпущен до того, как у вас закончится буферизация данных из последнего запроса. Можно попытаться повторно использовать одно и то же TCP-соединение для всех запросов (т. Е. Поддерживать HTTP), но нужно иметь дело с тем случаем, когда сервер отключает соединение, создавая новый.

Это способ Chrome делает это, это способ, который вписывается в дизайн HTTP, и это работает также, когда у одного есть только ограниченная RAM для хранения данных. И он должен работать с любым сервером, поддерживающим запрос Range, т. Е. Почти все. Если вы используете полный контроль над сервером, вы также можете использовать WebSockets или использовать протоколы, которые вообще не используют HTTP для транспортировки данных, но специально разработаны для вашего использования, например RTSP.

Дополнительное видео по вопросу: Преждевременный FIN, когда контент не закончился

Python Network Programming - TCP/IP Socket Programming

Python Network Programming 3 - Binding Socket and Connections ( Socket Programming )

Socket Programming Tutorial In C For Beginners | Part 1 | Eduonix