Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: raw & http  (Прочитано 7822 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Loki
Участник

ru
Offline Offline

« : 10-11-2008 12:33 » 

Подскажите как скачать файл попакетно 1 пакет за 1 сессию. Т.е. послав запрос получив 1 пакет закрыть сессию и открыть слудующую с новый значением range. Загвоздка вышла вот в чем...
вот ту  я собираю пакет в raw...

Код:
//......где-то там он начал собираться, а ниже склеиваются заголовки
dptr = (struct data *)(buffer+sizeof(struct iphdr)+sizeof(struct tcphdr)); // тут собирается пакет +данные.
// как засунуть в него http -запрос?
bzero(&pseudo, 12+sizeof(struct tcphdr));
pseudo.source_address = ip_header->saddr;
pseudo.dest_address = ip_header->daddr;
pseudo.placeholder = 0;
pseudo.protocol = IPPROTO_TCP;
pseudo.tcp_length = htons(sizeof(struct tcphdr));
bcopy((char *)tcp_header, (char *)&pseudo.tcp, sizeof(struct tcphdr));
tcp_header->check = in_cksum((unsigned short *)&pseudo,20+ sizeof(struct tcphdr));
// тут по идее нужно как-то в рав засунуть протокол 4 уровня http с таким заголовким...
httpRequest(remote_ip_str, remote_port,
"GET "+url+" HTTP/1.0\r\n"
"Host: "+host+"\r\n"
"Cache-Control: no-cache\r\n"
"Pragma: no-cache\r\n"
"Content-Range: bytes "+start_len+"-"+end_len+"/-1\r\n"
"\r\n", buffer);
close(sock);
return 0;
}
void httpRequest(char host, int remote_port, int start_len, int end_len, char url, char *buffer) {
char *buf, int len, int bufsize;
// потом тут как-то ресивить пакет, верифаить что это 1 пакет, открывать новую сессию
}
Придумал ограничивать скачивание 1 пакета по Content-Range. заранее предусмотрев знавение которое точно войдет в данные 1 пакета ресива.
Вот, подскажите как запихнуть http- заголовок в raw и как дальше принимать по 1 пакету?
p.s. возможно есть другой способ не юзая Content-Range, если есть, поделитесь пожалуйста.

p.p.s. не в тот раздел =) елси можно в чистый Си пернести.
« Последнее редактирование: 10-11-2008 21:43 от Loki » Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 10-11-2008 15:31 » 

Offtopic:

PPPS вам не угодишь)
раньше надо было думать Жжешь
Поставлю в угол.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Loki
Участник

ru
Offline Offline

« Ответ #2 : 11-11-2008 12:02 » 

Возник еще вопрос...
Если я реализую http- заголовок в виде структуры, например как у меня выше по коду...
Код:
struct data{
char url[];
char host[];
int start_len;
int end_len
}data;
только вот становится немного не ясно, как передать не только сами значения которые мне нужны,
а весь заголовок, тип метода итд...
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 11-11-2008 19:59 » 

Цитата: Loki
Подскажите как скачать файл попакетно 1 пакет за 1 сессию. Т.е. послав запрос получив 1 пакет закрыть сессию и открыть слудующую с новый значением range.
Какой пакет? IP-пакет? TCP-сегмент?

Раз речь идёт про HTTP, то для него последним уровнем, где наблюдаются "пакеты", будет TCP. В этом случае ответ: никак. Размер сегментов в TCP выбирается автоматически в зависимости от качества канала связи и скорости работы общающихся хостов. Кроме того, процедура передачи данных по этому протоколу подразумевает обмен множеством пакетов в процессе установки и поддержания работы канала и обеспечения гарантированной доставки данных. И программисту всё это "хозяйство" не видно, поскольку его не касается.

Размер датаграммы можно определять в UDP, но в этом протоколе нет понятия канала или сессии. И, кроме того, я не знаю, есть ли реализации HTTP поверх UDP.

IMHO, либо постановка задачи абсурдна, либо под "пакетом" понимается что-то совсем другое, например, HTTP-запрос. Но в HTTP на уровне протокола нет понятия сессии. Сессии web-приложения - это уже дополнительные изобретения, привязанные к установленным каналам TCP.

Предлагаю автору темы определиться с тем, чего же он хочет на самом деле.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Loki
Участник

ru
Offline Offline

« Ответ #4 : 12-11-2008 12:43 » 

Цитата
Размер сегментов в TCP выбирается автоматически в зависимости от качества канала связи и скорости работы общающихся хостов.
Вообще это mtu по дефолну сетевое окно 1500 на езернете.

Хм, в прочем нужно качать по range, например по 9Kb за запрос.
Тотлько вот как узнать что файл закончился? Предварительно послать HEAD и вытащить len? Еще есть варианты как вовремя остановить закачку при оконцании файла?
« Последнее редактирование: 12-11-2008 13:03 от Loki » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 12-11-2008 13:19 » 

Цитата: Loki
Вообще это mtu по дефолну сетевое окно 1500 на езернете.
Термин "окно" - это термин TCP. Он означает количество переданных источником байтов без подтверждения о получении их приёмником. Чем хуже канал связи, тем меньше окно. Передача данных осуществляется серией пакетов, после чего приёмник посылает источнику пакет подтверждения приёма всего окна. Если такого не происходит, источник может повторять попытки, уменьшать окно и т.д.

Термин MTU (maximum transmission unit), действительно, применим к протоколу Ethernet, и означает максимальное количество данных, которое может передаваться в одном фрейме.

Для оптимизации передачи данных в Ethernet-сети значения MTU на разных хостах согласуют между собой.

Но причём тут HTTP, передача файлов и т.п.?

Уже затронуты 2-й (канальный - Ethernet), 4-й (транспортный - TCP) и 7-й (прикладной - HTTP) уровни сети, между которыми нет и быть не может никакой связи, кроме того, что передаваемые данные проходят по стеку протоколов. И при передаче данных на любом уровне можно ожидать смены протокола (скажем, на магистралях Internet вовсе не Ethernet используется).

И в чём тогда состоит задача?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Loki
Участник

ru
Offline Offline

« Ответ #6 : 12-11-2008 13:29 » 

Цитата
Чем хуже канал связи, тем меньше окно. Если такого не происходит, источник может повторять попытки, уменьшать окно и т.д.
Меняет окно автоматически? Это как-то реализуется в сервере или просто так работает протокол сам по себе?
Цитата
И в чём тогда состоит задача?
Как узнать что файл закончился? Предварительно послать HEAD и вытащить len? Еще есть варианты как вовремя остановить закачку при оконцании файла? Или по recvfrom, если не нуль, как лучше? Хотя если проверка на 0 recvfrom, а я качаю по range, то не ясно что произойдет если произойдет запрос значения range больше чем сам файл?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 12-11-2008 14:29 » 

Цитата: Loki
Меняет окно автоматически?
Да.
Цитата: Loki
Это как-то реализуется в сервере или просто так работает протокол сам по себе?
Странный вопрос: а протокол где работает? Улыбаюсь Это делается на хосте в реализации протокола согласно описанию протокола.

Цитата: Loki
Как узнать что файл закончился? Предварительно послать HEAD и вытащить len? Еще есть варианты как вовремя остановить закачку при оконцании файла?
Согласно протоколу HTTP в начале идёт заголовок, где можно указать размер запроса (и в GET, и в POST, и в HEAD запросе) или ответ - если не ошибаюсь, поле Content-Length. Дальше просто сравнить реальный размер с запроса с продекларированным в заголовке.

И зачем огород городить с пакетами и MTU?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 12-11-2008 17:58 » 

Описание протокола HTTP 1.1: http://www.faqs.org/rfcs/rfc2616.html

Есть еще один способ узнать длину файла, если сервер не передал заголовок Content-Length: сделать запрос на часть файла и в ответе в заголовке Content-Range _может_ быть указана полная длина после слеша. Если указывается "*", то значит не судьба - значит сервер сам не знает размер файла (вероятно, он выдается скриптом, который не создал необходимый заголовок Content-Length).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines