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

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

ua
Offline Offline

« : 04-02-2012 12:35 » 

Всем привет, у меня вот такая проблемка - приходит пакет HTTP в формате GZIP. Конечно же приходит он у меня в буфере, мне нужно провести декомпрессию и продолжить работать с данным буфером.
Я смотрел по поиску темы по GZIP здесь, они что-то непонятны мне. Офф сайт тоже(((
Буду очень признателен если добрый человек напишет простой код подключения gzip библиотеки и работы с ней (только буфер на вход, буфер на выход).
Еще такой вопрос - вожможно декомпреснуть не весь буфер а часть его, тоисть или у gzip проходит декомпрессия побайтово, связана ли она с следующими байтами?
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #1 : 04-02-2012 12:53 » 

dimaslviv, с чем ты работаешь? Сокет, захват пакетов, еще с чем?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
dimaslviv
Участник

ua
Offline Offline

« Ответ #2 : 04-02-2012 12:58 » 

Я работаю в Visual Studio 2010. С сокетами не работаю, у меня есть файл с пакетами который нужно разобрать. Задача заключается в том чтобы написать парсер HTTP пакетов
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #3 : 04-02-2012 14:32 » 

Понял: рация на бронетранспортере. Ага

Дело в том, что сжаты не пакеты, а поток (TCP - потоковый протокол). Т.ч. сперва придется собрать поток. Даже частичное декодирование можно выполнить только начиная с начала потока.

Библиотека zlib сишная.

Самое простое - декодировать все данные сразу (функция uncompress):
http://zlib.net/manual.html#Utility

Если нужно декодировать поток:
Контекст хранится в структуре z_stream:
http://zlib.net/manual.html#Stream
Структуру надо заполнить, проинициализировать (inflateInit), по добалению данных вызывать deflate и в конце закрыть (deflateEnd).
http://zlib.net/manual.html#Basic

В комплекте с zlib идет пример: example.c
Оттуда пример:

Код: (C)
void test_deflate(compr, comprLen)
    Byte *compr;
    uLong comprLen;
{
    z_stream c_stream; /* compression stream */
    int err;
    uLong len = (uLong)strlen(hello)+1;

    c_stream.zalloc = (alloc_func)0;
    c_stream.zfree = (free_func)0;
    c_stream.opaque = (voidpf)0;

    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
    CHECK_ERR(err, "deflateInit");

    c_stream.next_in  = (Bytef*)hello;
    c_stream.next_out = compr;

    while (c_stream.total_in != len && c_stream.total_out < comprLen) {
        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
        err = deflate(&c_stream, Z_NO_FLUSH);
        CHECK_ERR(err, "deflate");
    }
    /* Finish the stream, still forcing small buffers: */
    for (;;) {
        c_stream.avail_out = 1;
        err = deflate(&c_stream, Z_FINISH);
        if (err == Z_STREAM_END) break;
        CHECK_ERR(err, "deflate");
    }

    err = deflateEnd(&c_stream);
    CHECK_ERR(err, "deflateEnd");
}
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
dimaslviv
Участник

ua
Offline Offline

« Ответ #4 : 07-02-2012 11:01 » 

Спасибо, кажись решил проблемку)
Записан
dimaslviv
Участник

ua
Offline Offline

« Ответ #5 : 12-03-2012 15:36 » 

Функции для работы с файлами нормально работают но не с буффером, может что-то упускаю
Функция uncompress возвращает -3(некомпрессированые данные на входе)
Начало буфера кажеться правильно описано:
 1f 8b 08 00 00 00 00 00 00 03 94 53 db 8e a2
« Последнее редактирование: 12-03-2012 15:38 от dimaslviv » Записан
RXL
Технический
Администратор

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

WWW
« Ответ #6 : 12-03-2012 16:17 » 

"Кажется" - к точным наукам не относится. Программирование, напомню, является разделом математики.

dimaslviv, лучше код показывай - биты и байты разглядывать совсем не интересно.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
dimaslviv
Участник

ua
Offline Offline

« Ответ #7 : 13-03-2012 11:53 » 

Код: (C++)
#include "zlib.h"
typedef  int __stdcall f1(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
int main()
{
        f1 *f;
        HMODULE hDLL = LoadLibraryW(L"E:\\zlibwapi.dll");
        f = (f1*)GetProcAddress(hDLL, "uncompress");
        FILE *fin, *fout;
        fin = fopen("E:\\file50.html.gz", "rb");
        fout= fopen("E:\\file50.html", "ab");
        if(!fin || !fout)
                cout << "err open files" << endl;
        fseek(fin, 0, SEEK_END);
        UINT32 sizeIN = ftell(fin);
        fseek(fin, 0, SEEK_SET);
        BYTE* inBUFF = new BYTE[sizeIN];
        fread(inBUFF, sizeIN, 1, fin);
        ULONG reff = sizeIN*20;
        BYTE* outBUFF = new BYTE[reff];
        errno_t er = f(outBUFF, &reff, inBUFF, sizeIN);
        fclose(fin);
}      

код ошибки -3
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #8 : 13-03-2012 13:26 » 

Где произошла ошибка?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
dimaslviv
Участник

ua
Offline Offline

« Ответ #9 : 13-03-2012 15:43 » new

при использовании функции f(),
она вернула значение -3

Добавлено через 4 минуты и 45 секунд:
я еще пробовал тоже зделать через функции inflate()  - так она тоже возвращает -3 и пишет в msg "incorrect header check".
Не исключено что ее я тоже неверно написал.

Этот файл нормально декомперссируется через функции gzopen -> gzread. Не могу понять в чем может быть разница при использовании функций работы с буффером
« Последнее редактирование: 13-03-2012 15:48 от dimaslviv » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #10 : 13-03-2012 16:54 » 

Если не ошибаюсь, то там присутствует заголовок gzip-а (раз уж у Вас он нормально открывается через gzopen()), а уже потом сам поток сжатых байтов. Возможно необходимо вызвать inflateInit2() с соответствующим значением windowBits. Для простых файлов в формате gzip, у меня работало значение 31.
Записан
dimaslviv
Участник

ua
Offline Offline

« Ответ #11 : 14-03-2012 13:03 » 

darkelf, спасибо, действительно помогло.
Кстати может бывает вероятность размера окна не 31?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #12 : 14-03-2012 13:17 » 

dimaslviv, почитайте документацию, там оно не совсем окно, точнее окно, но как-бы с флагами (16 и 32)
Записан
dimaslviv
Участник

ua
Offline Offline

« Ответ #13 : 14-03-2012 13:40 » 

ок, спасибо за помощь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines