LINUX.ORG.RU

raw & http


0

0

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

//......где-то там он начал собираться, а ниже склеиваются заголовки
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, если есть, поделитесь плиз.
anonymous

зачем тебе всё это? зачем тебе вообще опускаться на уровень tcp-протокола? в чем вообще задача заключается?

xydo ★★
()
Ответ на: комментарий от xydo

->зачем тебе всё это? зачем тебе вообще опускаться на уровень tcp-протокола? в чем вообще задача заключается?
ой, лучше не спрашивайте, а если есть предложения подсказывайте.
Просто хочу во всем разобраться как оно устроено на собственных 
фелосипедах, авось оптом где-нибуть да аукнится.

anonymous
()

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

alex4
()

curl, libcurl тебе в помощь

anonymous
()

Вы RFC на TCP читали? Там сначала идет SYN пакет, идет согласование параметров соединения. Это не так просто реализовать tcp-протокол через raw-сокет. Причем, нужно реализовать правильно, т.к. получая пакет нужно отправлять подтверждения, а закончив читать нужно разрывать соединение. Иначе получится, что ваша программа будет открывать кучу соедиенений на сервере == DOS.

mky ★★★★★
()
Ответ на: комментарий от mky

хм, про syn\syn+ask в курсе, это учнено, ну да тогда получается нужно принять 2 пакета.
Только вот еще вопрос, как засунуть http-запрос в raw-пакет?
Вот как я его собираю с дынными...
dptr = (struct data *)(buffer+sizeof(struct iphdr)+sizeof(struct tcphdr));
Получается можно тупо в data засовывать строчку с методом GET?

anonymous
()
Ответ на: комментарий от anonymous

запусти wireshark/ethereal и посмотри, как пакеты бегают

anonymous
()
Ответ на: комментарий от anonymous

>авось оптом где-нибуть да аукнится.

это может пригодится только если ты будешь разработчиком ОС.

>Просто хочу во всем разобраться как оно устроено

так разбирайся по очереди.

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

и разберись с тем, что выполняет каждый слой. имхо, этого будет более, чем достаточно. ибо ничего кроме банального добавления заголовков там нет. (разве что дополнительные сервисные пакеты, подтверждения приема, например)

если интересно формирование пакетов или организация работы нескольких разношерстных протоколов - смотри в код Линукса. правда там на несколько порядков посложнее, чем в твоем примере. но зато это работает.

xydo ★★
()
Ответ на: комментарий от anonymous

>Получается можно тупо в data засовывать строчку с методом GET?

нет, в общем случае нельзя.

почему? потому что данными для протокола одного уровня служит пакет, сформированный протоколом уровня выше...

опять-таки повторяю, читай (для начала на Вики) про сетевую модель... многие вопросы сами отпадут.

и как уже посоветовали - послушай траффик каким-нибудь сниффером с распечаткой дапма пакетов (отфильтруй только по нужным портам, нето будет такой винегрет...)

xydo ★★
()
Ответ на: комментарий от xydo

->запусти wireshark/ethereal и посмотри, как пакеты бегают
там pcap юзается, у меня raw

->почему? потому что данными для протокола одного уровня служит пакет, сформированный протоколом уровня выше... 
Да, именно по этому я собираю tcp-пакет с данными вот так...
dptr = (struct data *)(buffer+sizeof(struct iphdr)+sizeof(struct tcphdr));
Если я реализую http- заголовок в виде структуры, например как у меня выше по коду...
struct data{
char url[];
char host[];
int start_len;
int end_len
}data;
только вот становится немного не ясно, как передать не только сами значения которые мне нужны, 
а весь заголовок, тип метода итд...

anonymous
()
Ответ на: комментарий от anonymous

>а весь заголовок, тип метода итд...

Ну формируете нужную строку, допустим с помощью snprintf:

snprintf(buf, BUFSZ, "GET %s HTTP/1.0\r\nHost: %s\r\n и так далее", data.url, data.host, и так далее)

и передаете эту строку. Но только полезная нагрузка пакета будет меньше 1500 байт, длинный url не влезет.

Может вам лучше сначала разобраться как работать через raw-сокет c udp пакетам? Допустим с DNS-сервером. Думаю, тогда многие вопросы отпадут.

mky ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.