Файловый WEB сервер
- Войдите на сайт для отправки комментариев
Пт, 16/01/2015 - 02:43
Доброго времени суток! Пытаюсь реализовать файловый веб сервер на базе Arduino mega и Ethernet shild v3. Все основные функции написаны, контроллер считывает содержимое SD карты, формирует веб страницу со ссылками на файлы при клике на которые открывается диалоговое окно сохранения файла, но...!
Не могу передать содержимое самого файла. Файлы скачиваются нулевого размера. Вот кусок кода:
client.print("HTTP/1.1 200 OK"); client.print("Content-Description: File Transfer"); client.print("Content-Type: application/octet-stream"); client.print("Content-Disposition: attachment; filename="); client.print(getFileName); client.print("Content-Transfer-Encoding: binary"); client.print("Expires: 0"); client.print("Cache-Control: must-revalidate"); client.print("Pragma: public"); client.print("Content-Length: "); client.print(myFile.size()); while (myFile.available()) { client.write(myFile.read()); }
Сами файлы открываются нормально, могу вывести содержимое в консоли, но передаваться по hhtp не хочет. Установил сниффер, запустил закачку файла с какого то сайта. Судя по пакетам, сами данные передаются в TCP пакетах, но как это реализовать, не понимаю.
Сама WEB страница открывается ? Не открываются только картинки ?
И з вашего кода видно только отправка заголовка и перекачка файла, к стати без его открытия перед 11 строкой имеет смымл открыть myFile
Да, страница открывается, так же как и файл. Привожу код скачивания файла:
Была ошибка. Fiddler мне подсказал что заголовок должен заканчиваться на /r/n/r/n, т.е. в конце заголовка надо было добавить пустую client.println();, но это не исправило положение, файл не скачивается
Из сниффера видно, что файл от сервера передается, но как то странно, по одному байту в пакете.
Похоже дело именно в этом, передавать данные необходимо скопом, иначе каждый считанный из файла байт формирует свой пакет передачи. Попробовал передать client.write("aaaaaaaaaaaaaaaaaaaaaaaa"); Файл скачался нормально, в сниффере все эти аааа... в одном пакете.
Теперь вопрос, как передать содержимое файла за один присест, а не побайтно?
Читаешь кусок файла в буфер и кидаешь кусками. Только под буфер память нужна.
Ну ладно, первый кусок я так скину, а второй кусок пойдет отдельным пакетом, не привязанным к первому?
Наверняка кто то заморачивался по поводу пересылки файла по сети стандартными средствами, например SMB или FTP?
я вот так скачиваю,правда без запроса,сразу качает...побайтно...а вас почему это напрягает?из за времени передачи?у меня файлы текстовые все,мне особо не мешает,по байтам ну и пусть,10сек и файл у меня..
Да мне не принципиально, хоть побитно, лишь бы качал. Спасибо заинформацию, буду пробовать
А файловый сервер будет доступен с глобальной сети ? Или только локально ?
ну,по сути наши скетчи практически не отличаются,только я в конце закрываю соединение с клиентом,видимо у вас на этом заминка..delay перед этим положительно влияет,меньше сбоев,браузеру нужно время полностью обработать инфу,не убирайте совсем,можно уменьшить немного опытным путем...
Только локально, в глобальной сети думаю тормоза будут дикие с однобайтной пересылкой, там даже страница побайтно формируется, проверял
Читать до полного просветления http://arduino.cc/en/Reference/ClientWrite
не скажи=)у меня как раз все через интернет...так мало того,у ардуины интернет 3g с юсб модема с хреноватым сигналом ,ардуина собственно сама еще и смотрит есть связь или нет и перегружает модем если че,и все ок=)так что не боись..
ну,по сути наши скетчи практически не отличаются,только я в конце закрываю соединение с клиентом,видимо у вас на этом заминка..delay перед этим положительно влияет,меньше сбоев,браузеру нужно время полностью обработать инфу,не убирайте совсем,можно уменьшить немного опытным путем...
Ааа!!! Заработало!
Дело не в закрытии соединения, оно у меня закрывается далее по коду, дело именно в заголовке, похоже один из параметров указанных мной, как раз запрещает отправку данных побайтно, буду смотреть.
Спасибо огромное!
Читать до полного просветления http://arduino.cc/en/Reference/ClientWrite
Если это тонкий намек на то, что write умеет отсылать данные серией байтов, то я это знал, но это не решает проблемы. Как отправить вторую, третью и т.д. порцию данных, чтобы это было продолжением первого пакета (это пакеты помеченные как "continuation")? Для этого необходимо залезть в заголовок TCP. Ну или как вариант загрузить весь файл в память и отправить его целиком, наверное так получится если памяти хватит.
И еще один момент, если при отправке данных с помощью write или print используются переменные, они автоматически фрагментируются по пакетам, например:
client.print("Open file: test.txt"); - упакуется в один пакет
String fileName = "test.txt";
client.print("Opent file: " + fileName); - разобьется на множество tcp пакетов по одному байту полезной информации в каждом
Ну покрайне мере мои эксперементы со сниффером показали имено это
А Fiddler`у не понравился такой заголовок, говорит No Connection: close, no Content-Length. No way to tell if the response is complete.
Странно, буду смотреть
Может пригодится, проверено работает, открывает, качает. Одно но, стабильно работает на меге 2560.
Лишнее можно обрезать, выкинуть.
Ого, сколько тут всего полезного, спасибо!
полезный скетч,спасибо...