GZipStream, как правильно читать из GZipStream

У меня есть код, написанный мной на C #

        string host = new Uri(_url).Host;
        IPHostEntry ipAddress = Dns.GetHostEntry(host);
        IPEndPoint ip = new IPEndPoint(ipAddress.AddressList[0], 80);
        using (Socket s = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
        {
            s.Connect(ip);
            using (NetworkStream n = new NetworkStream(s))
            {
                    byte[] write = encoding.GetBytes(HttpQuery);
                    n.Write(write, 0, write.Length);
                    ReadLine(n);
                    Dictionary<string, string> headers = new Dictionary<string, string>();
                    while (true)
                    {
                        string line = ReadLine(n);
                        if (line.Length == 0)
                        {
                            break;
                        }
                        int index = line.IndexOf(':');
                        if (!headers.ContainsKey(line.Substring(0, index)))
                        {
                            headers.Add(line.Substring(0, index), line.Substring(index + 2));
                        }
                    }

                    string contentEncoding;
                    if (headers.TryGetValue("Content-Encoding", out contentEncoding))
                    {
                        Stream responseStream = n;
                        if (contentEncoding.Equals("gzip"))
                        {
                            responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                            responseStream.Flush();
                        }
                        else if (contentEncoding.Equals("deflate"))
                        {
                            responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                        }

                        MemoryStream memStream = new MemoryStream();

                        byte[] respBuffer = new byte[4096];
                        try
                        {
                            int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
                            //int bytesRead = responseStream.ReadByte();
                            while (bytesRead > 0)
                            {
                                memStream.Write(respBuffer, 0, bytesRead);
                                bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
                            }
                        }
                        finally
                        {
                            responseStream.Close();
                        }
                        string str = encoding.GetString(memStream.ToArray());

Тогда у меня есть исключение InvalidDataException в этой строке int bytesRead = responseStream.Read (respBuffer, 0, respBuffer.Length);

Неправильный магический номер заголовка GZip.

    string ReadLine(Stream stream)
    {
        List<byte> lineBuffer = new List<byte>();
        try
        {
            while (true)
            {
                int b = stream.ReadByte();
                if (b == -1)
                    return null;
                if (b == 10)
                    break;
                if (b != 13)
                    lineBuffer.Add((byte) b);
            }
        }
        catch (Exception)
        {
        }
        return encoding.GetString(lineBuffer.ToArray());
    }

Любые идеи?


person IICuX    schedule 06.02.2010    source источник
comment
Не изобретайте колесо, класс HttpWebResponse уже делает это.   -  person Hans Passant    schedule 06.02.2010


Ответы (2)


Ваша функция ReadLine возвращается, как только она считывает один символ перевода строки при чтении пустой строки. Разве это не оставляет поток, расположенный на символе возврата каретки, а не в начале потока данных GZip?

person BlueMonkMN    schedule 06.02.2010

в общем, я кое-что нашел по теме, вот Сокеты в C # : Как получить поток ответа?, есть некоторая информация перед строкой (строками) для этого:

                        Stream responseStream = n;
                        int magicNumber = 0;
                        while (magicNumber != 10)
                        {
                            magicNumber = responseStream.ReadByte();
                        }
                        if (contentEncoding.Equals("gzip"))
                        {
                            responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                        }

может я не совсем правильно сделал?

nobugz У меня есть очень успешный код, написанный с помощью WttWebRequest и HttpWebResponse, НО моя страница имеет codepape-1251, а HttpWebRequest конвертирует URL-адрес из кодировки 1251 в UTF-8, и я ничего не могу сделать с этим, может у вас есть идеи?

Например, у меня URL-адрес http://myurl.php?Name=%D0%9C%D0%B0%D1%81%D1%82%D0%B5%D1%80%20%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D0%B5%D0%BB%D1%8C

HttpWebRequest преобразует это в http://myurl.php?name=%d0%9c%d0%b0%d1%81%d1%82%d0%b5%d1%80+%d0%a1%d0%be%d0%b7%d0%b4%d0%b0%d1%82%d0%b5%d0%bb%d1%8c (UTF-8)

НО будет http://myurl.php?Name=%CC%E0%F1%F2%E5%F0%20%D1%EE%E7%E4%E0%F2%E5%.EB%FC (windows-1251), я не знаю, как это исправить

person IICuX    schedule 06.02.2010
comment
Почему проблема с кодировкой URL-адреса? Вы пытаетесь обработать содержимое gzip в ответе, а не URL-адрес, верно? Связан ли этот вопрос с вашим исходным вопросом как-то? - person BlueMonkMN; 09.02.2010