Загрузка больших файлов через HTTP

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

Ответ 1

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

1) HEAD удаленный файл

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

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

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

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

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

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

Ответ 2

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

  • Вы отправляете запрос на загрузку с указанием имени файла и его размера, а также количества начальных потоков.
  • ваш php-код создаст временную папку с именем после IP-адреса и имени файла,
  • Затем ваше приложение может использовать MULTIPLE-соединения для отправки данных в разных потоках, чтобы вы могли одновременно отправлять куски 1,111,212,313 (с отдельными контрольными суммами).
  • ваш php-код сохраняет их в разные файлы и подтверждает прием после проверки контрольной суммы, предоставления номера нового фрагмента для отправки или остановки с этим потоком.
  • После того, как все потоки закончены, вы попросите php присоединиться ко всем файлам, если что-то не хватает, оно будет иметь 3

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

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

Ответ 3

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

Антон Гоголев Лол, я просто думал об одном и том же - реверсировал все, сделав сервер клиентом, а клиент - сервером. спасибо to Roel, почему это не сработает, теперь яснее.

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

Ответ 8

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