Загрузка больших файлов по HTTP - PullRequest
13 голосов
/ 29 января 2009

Мне нужно выгрузить потенциально большие (от 10 до 100 мегабайт) файлы из настольного приложения на сервер. Код сервера написан на PHP, настольное приложение на C ++ / MFC. Я хочу иметь возможность возобновить загрузку файлов, когда загрузка не удалась на полпути, потому что это программное обеспечение будет использоваться по ненадежным соединениям. Какие у меня варианты? Я нашел несколько компонентов HTTP-загрузки для C ++, таких как http://www.chilkatsoft.com/refdoc/vcCkUploadRef.html, который выглядит превосходно, но, похоже, он не обрабатывает «возобновление» половины выполненных загрузок (я полагаю, это потому, что HTTP 1.1 не ' не поддерживает это). Я также посмотрел на службу BITS, но для загрузки требуется сервер IIS. Пока что мой единственный вариант - разрезать файл, который я хочу загрузить, на более мелкие части (скажем, по 1 МБ каждый), загрузить их все на сервер, собрать их с помощью PHP и запустить контрольную сумму, чтобы проверить, все ли прошло нормально. Чтобы возобновить, мне нужно было иметь некоторую форму «рукопожатия» в начале загрузки, чтобы узнать, какие части уже находятся на сервере. Придется ли мне кодировать это вручную или кто-нибудь знает библиотеку, которая делает все это для меня, или, может быть, даже совершенно другое решение? Я бы не стал переключаться на другой протокол, который изначально поддерживает возобновление по причинам обслуживания (потенциальные проблемы с брандмауэрами и т. Д.)

Ответы [ 8 ]

20 голосов
/ 30 сентября 2009

Я опоздал на восемь месяцев, но я наткнулся на этот вопрос и был удивлен, что webDAV не упоминается. Вы можете использовать метод HTTP PUT для загрузки и включить заголовок Content-Range для обработки возобновления и тому подобное. Запрос HEAD скажет вам, если файл уже существует и насколько он большой. Так что, возможно, что-то вроде этого:

1) HEAD удаленного файла

2) Если он существует и имеет размер == локальный размер, загрузка уже выполнена

3) Если размер <локальный размер, добавьте заголовок Content-Range для запроса и найдите соответствующее местоположение в локальном файле. </p>

4) Сделать PUT-запрос на загрузку файла (или части файла, если он возобновляется)

5) Если во время запроса PUT происходит сбой соединения, начните заново с шага 1

Вы также можете перечислять (PROPFIND) и переименовывать (MOVE) файлы, а также создавать каталоги (MKCOL) с помощью dav.

Я считаю, что и Apache, и Lighttpd имеют расширения dav.

2 голосов
/ 09 октября 2009

libcurl (C api) может быть приемлемым вариантом

-C / - продолжение-в Продолжить / возобновить предыдущую передачу файла с заданным смещением. Данное смещение является точным числом байтов, которые будут пропущены, считая от начала исходного файла до его передачи в место назначения. При использовании с загрузками команда FTP-сервера SIZE не будет использоваться curl. Используйте «-C -», чтобы указать curl, чтобы автоматически выяснить, где / как возобновить передачу. Затем он использует заданные файлы вывода / ввода, чтобы выяснить это. Если эта опция используется несколько раз, будет использоваться последняя

2 голосов
/ 30 января 2009

Вам нужен стандартный размер (скажем, 256 КБ). Если ваш файл "abc.txt", загруженный пользователем x, равен 78,3 МБ, это будет 313 полных блоков и один меньший фрагмент.

  1. Вы отправляете запрос на загрузку с указанием имени файла и размера, а также количества исходных потоков.
  2. Ваш php-код создаст временную папку, названную в честь IP-адреса и имени файла,
  3. Ваше приложение может затем использовать НЕСКОЛЬКО подключений для отправки данных в разные потоки, поэтому вы можете отправлять куски 1 111 212 313 одновременно (с отдельными контрольными суммами).
  4. Ваш php-код сохраняет их в разных файлах и подтверждает прием после проверки контрольной суммы, указания номера нового чанка для отправки или остановки в этом потоке.
  5. После того, как все потоки завершены, вы должны попросить php присоединиться ко всем файлам, если что-то не хватает, он перейдет к 3

Вы можете увеличивать или уменьшать количество потоков по желанию, поскольку приложение контролирует отправку.

Вы можете легко отобразить индикатор прогресса, либо простой индикатор выполнения, либо что-то близкое к подробному представлению downthemall о кусках.

1 голос
/ 04 августа 2012

Google создал протокол возобновляемой загрузки HTTP. Смотри https://developers.google.com/gdata/docs/resumable_upload

0 голосов
/ 18 июля 2013

F * EX может загружать файлы до диапазона TB через HTTP и может возобновить работу после сбоя соединения. Он не совсем соответствует вашим потребностям, потому что он написан на Perl и требует сервера на базе UNIX, но клиенты могут быть в любой операционной системе. Может быть, это все же полезно для вас: http://fex.rus.uni -stuttgart.de /

0 голосов
/ 13 ноября 2010

@ Антон Гоголев Лол, я просто думал об одном и том же - полностью изменил ситуацию, сделав сервер клиентом, а клиент - сервером. Спасибо Роелю, почему это не сработает, теперь мне понятнее.

@ Роэль Я бы предложил реализовать загрузчик Java [JumpLoader хорош с его интерфейсом JScript и даже примером PHP-кода на стороне сервера]. Flash-загрузчики сильно страдают, когда дело доходит до файлов BIIIGGG :), в гигабайтном масштабе.

0 голосов
/ 29 января 2009

Возможно, самый простой способ - создать страницу загрузки, которая будет принимать имя файла и диапазон в параметре, например http://yourpage/.../upload.php?file=myfile&from=123456, и обрабатывать резюме в клиенте (возможно, вы можете добавить функцию для проверки того, какой диапазон сервер получил)

0 голосов
/ 29 января 2009

Можно ли полностью изменить процесс? Я имею в виду, вместо того, чтобы передавать файл на сервер, заставить сервер извлекать файл, используя стандартный HTTP GET со всеми прибамбасами (например, диапазоны принятия и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...