С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
2 / 2 / 1
Регистрация: 16.05.2013
Сообщений: 69

Как распаковать ответ сервера в формате Gzip?

13.05.2015, 14:01. Показов 3509. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. У меня проблема при попытке разархивировать ответ от одного сайта, сжатый с помощью gzip.

Вот мой метод:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
string Ungzip(MemoryStream m1)
        {
 
            string page = "";
            Encoding enc = Encoding.UTF8;
            byte[] bytesReceived = m1.ToArray();
            try
            {
                for (int i = 0; i < bytesReceived.Length; i++)
                {
                    if (bytesReceived[i] == 13 &&
                        bytesReceived[i + 1] == 10 &&
                        bytesReceived[i + 2] == 13 &&
                        bytesReceived[i + 3] == 10)
                    {
                        var b = bytesReceived.Take(i).ToArray();
                        page = enc.GetString(b, 0, b.Length);
                        bytesReceived = bytesReceived.Skip(i+4).ToArray();
                        break;
                    }
                }
 
                    GZipStream myGzip = new GZipStream(new MemoryStream(bytesReceived), CompressionMode.Decompress);
                    using (MemoryStream m = new MemoryStream())
                    {
                        byte[] buffer = new byte[1000];
                        int len = 0;
                        while ((len = myGzip.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            m.Write(buffer, 0, len);
                        }
                        bytesReceived = m.ToArray();
                    }
                    page += enc.GetString(bytesReceived, 0, bytesReceived.Length);
                
            }
            catch {}
 
            return page;
        }

В цикле происходит поиск строки "\r\n\r\n" и отсечение верхней части, это заголовки ответа сервера. А то что ниже остается - это само тело страницы сжатое в gzip. И вот с этим проблема, метод myGzip.Read выдает исключение при попытке прочитать в буфер данные:

System.IO.InvalidDataException: Неправильное магическое число в заголовке GZip. Передача должна идти в поток GZip.


Собственно не могу найти что это за число и почему возникает тут эта ошибка, так как данные приходят в запакованном виде, это видно через fiddler.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.05.2015, 14:01
Ответы с готовыми решениями:

Не декодируется gzip ответ сервера
Здравствуйте. Ответ сервера приъодит в формате gzip. Но почему-то после получения он выглядит так: Код клиента public...

Как прочитать ответ от сервера в формате JSON
Здравствуйте. В программировании я недавно. Пишу сейчас одну программу в Visual Studio 2012. Проблема такая. Надо из вот этого: ...

Boost.Asio. Как получить ответ от сервера в формате json или xml
Все привет, столкнулся с проблемой. Допустим, с помощью boost.asio и OpenSSL я делаю GET запрос сайту, пусть это будет api.vk.com. С...

11
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
13.05.2015, 18:55
А как вы получаете MemoryStream m1? Просто есь более простые способы, но они зависят от того какием способом вы получаете ответ от сервера.
https://msdn.microsoft.com/en-... .100).aspx
https://msdn.microsoft.com/en-... .118).aspx
0
2 / 2 / 1
Регистрация: 16.05.2013
Сообщений: 69
13.05.2015, 20:02  [ТС]
Вот такой вот пост запросик

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using (s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                                {
 
                                    s.Connect(host, 80);
                                    parametres = "some post params";
                                    byte[] ByteArr = Encoding.UTF8.GetBytes(parametres);
                                    requestS =
                                    "POST http://" + host + " HTTP/1.1\r\n" +
                                    "Host: " + host +
                                    "\r\nConnection: close\r\n" +
                                    "User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0\r\n" +
                                    "Accept-Encoding: gzip, deflate\r\n" +
                                    "Content-Length: " + ByteArr.Length +
                                    "\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n" +
                                    parametres;
 
                                    Byte[] bytesSent = Encoding.UTF8.GetBytes(requestS);
                                    Byte[] bytesReceived = new Byte[1000];
                                    s.Send(bytesSent, bytesSent.Length, 0);
                                    int bytes = 0;
                                    page = "";
                                    using (MemoryStream m = new MemoryStream())
                                    {
                                        do
                                        {
                                            bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
                                            m.Write(bytesReceived, 0, bytes);
                                        }
                                        while (bytes > 0);
                                        page = Ungzip(m);
                                    }
                                }
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
13.05.2015, 20:26
Ну так переделайте тогда на HttpWebRequest, кода станет в 10 раз меньше и все само распакуется.
0
2 / 2 / 1
Регистрация: 16.05.2013
Сообщений: 69
13.05.2015, 20:30  [ТС]
Интересует конкретно эта задача. HttpWebRequest мне не подходит, он медленный.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
13.05.2015, 20:34
Цитата Сообщение от SharpA Посмотреть сообщение
Интересует конкретно эта задача. HttpWebRequest мне не подходит, он медленный.
Может есть какие-то тесты, подтверждающие ваши слова? По мне так огород, который вы нагородили будет еще медленней.
0
2 / 2 / 1
Регистрация: 16.05.2013
Сообщений: 69
13.05.2015, 20:41  [ТС]
Someone007, пожалуйста, давайте уважать друг друга. Вы любезно порекомендовали решение, я любезно отказался, не об огороде или скорости тема, мне нужно понять причины по которым конкретное исключение может появляться. Спасибо за понимание!
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
13.05.2015, 20:50
Цитата Сообщение от SharpA Посмотреть сообщение
Someone007, пожалуйста, давайте уважать друг друга. Вы любезно порекомендовали решение, я любезно отказался, не об огороде или скорости тема, мне нужно понять причины по которым конкретное исключение может появляться. Спасибо за понимание!
Логично предположить что данное исключение появляется потому что данные, которые вы передаете в GZipStream не соответствуют ожидаемым? Например там у вас GZip без заголовка или что-то еще...

Добавлено через 4 минуты
Или вообще не GZip, а Deflate...
0
2 / 2 / 1
Регистрация: 16.05.2013
Сообщений: 69
13.05.2015, 20:53  [ТС]
А что насчет магического числа? Кто в курсе что это за конкретная последовательность байт?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
13.05.2015, 20:55
Цитата Сообщение от SharpA Посмотреть сообщение
что насчет магического числа? Кто в курсе что это за конкретная последовательность байт?
http://en.wikipedia.org/wiki/Gzip -> File format
0
2 / 2 / 1
Регистрация: 16.05.2013
Сообщений: 69
13.05.2015, 21:48  [ТС]
Проблема решена! Если кому будет нужно то вот в чем была проблема: массив байт в формата gzip должен начинаться с магического числа 1f 8b, что в числовом представлении 31 и 139, после чего идет непосредственно содержимое. У меня проблема была в том что я принимал ответ сервер и искал байтовое представление \n\r\n\r - эти символы отделяют хедер от тела страницы и я посчитал что сразу после этой последовательности будет идти магическое число, но вышло так что там было пару "мусорных" символов и GZipStream не увидел здесь правильного Gzip контента. Вобщем нужно обрезать массив так чтоб он начинался с 1f 8b. Всем спасибо!
1
0 / 0 / 0
Регистрация: 11.05.2015
Сообщений: 11
24.10.2015, 16:01
SharpA,
код в студию! с каментами!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.10.2015, 16:01
Помогаю со студенческими работами здесь

Извлечь значение url из ответ от сервера в формате JSON
Здравствуйте! Никак не могу освоить написание паттернов для Regex, а задачу решить всё же надо. Я подумал что мне будет больше понятно если...

Ajax -ответ сервера в формате XML в IE сразу выводится в окно
Не могу понять.В FF такой проблемы нет.Но в IE когда получает ответ в формате XML то вместо того чтобы его передать скрипту обработки...

Как распаковать игру в формате .*mdf
Подскажите пожалуйста распоковать игру в формате(mdf),а то голова уже идет кругом? Очень на ВАС надеюсь.

Авторизация на сайте по средствам POST запроса. Как расшифровать gzip ответ?
Всем привет, кто может мне помочь или кто тоже столкнулся с похожей проблемой! Проще говоря решил я сделать программу, которая будет...

Как распаковать заархивированные данные в формате *.arc
у меня глючит интсаляха,не может распаковать заархивированные данные в формате *arc,пробую в ручную ,чё то не один архиватор не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru