Socket HTTP頁面請求後對gzip頁面的解壓縮實現代碼

需要注意的有以下幾點:

 

1、通過socket頁面請求後的receive內容不能經過string後再進行解壓縮處理 會造成錯誤的gzip幻數報錯

      推薦使用流處理

2、正確分析返回內容 分割header和頁面代碼部分

3、對頁面代碼部分進行解壓縮

4、重組header與解壓縮後的頁面代碼

 

解壓縮使用net2.0的GZipStream類 很方便

 

代碼如下:

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO.Compression;
  5. using System.IO;
  6. using ICSharpCode.SharpZipLib.GZip;
  7. namespace 貼吧江湖
  8. {
  9.     public  class clsGzip
  10.     {
  11.         public static string DecompressGzip(MemoryStream stm)
  12.         {
  13.             string strHTML = "";
  14.           
  15.            
  16.             GZipStream gzip = new GZipStream(stm, CompressionMode.Decompress);//解壓縮
  17.             using (StreamReader reader = new StreamReader(gzip, Encoding.GetEncoding("gb2312")))//中文編碼處理
  18.             {
  19.                 strHTML = reader.ReadToEnd();
  20.             }
  21.             
  22.             return strHTML;
  23.         }
  24.     }
  25. }

socket類中對此方法的調用

 

  1. int bytes = 0;
  2.             string page = "";
  3.             MemoryStream ms = new MemoryStream();
  4.             
  5.             
  6.             
  7.             do
  8.             {
  9.                 bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
  10.                 
  11.                 //Encoding gb2312 = Encoding.GetEncoding("gb2312");//將讀取的字節數轉換爲字符串   
  12.                 //page = page + gb2312.GetString(bytesReceived, 0, bytes);
  13.                 ms.Write(bytesReceived, 0, bytes);
  14.                 
  15.                 //Console.WriteLine(bytes);
  16.             }
  17.             while (bytes > 0);
  18.             s.Close();
  19.             Console.WriteLine(ms.Length);
  20.             ms.Seek(0, SeekOrigin.Begin);//將流的讀寫位置移動到開頭
  21.             Encoding gb2312 = Encoding.GetEncoding("gb2312");//準備獲取HTTP header中頁面內容的大小
  22.             
  23.             page = new StreamReader(ms, gb2312).ReadToEnd();//將流讀入到字符串準備分割
  24.             string[] sArray = page.Split(new string[] { "/r/n/r/n" }, StringSplitOptions.RemoveEmptyEntries);//分割web服務器返回代碼 分爲頭域和頁面代碼
  25.             page = page.Substring(page.IndexOf("Content-Length: ") + 16);//分割字符串獲得頁面內容大小
  26.             page = page.Substring(0, page.IndexOf("/r/n"));
  27.             //Console.WriteLine(page);//輸出經過gzip壓縮的頁面內容的大小
  28.             long begin = ms.Length - Convert.ToInt64(page);//流長度-頁面內容大小就是我們需要的頁面內容在流內的起始位置
  29.             ms.Seek(begin, SeekOrigin.Begin);//移動到此位置
  30.             page = clsGzip.DecompressGzip(ms);//將流傳遞給解壓縮方法
  31.             //Console.WriteLine(begin);
  32.             page = sArray[0] + "/r/n/r/n" + page;//將header與解壓縮後的頁面內容重新組合
  33.             //Console.WriteLine(page);
  34.             return page;

發送頁面請求的時候注意加上Accept-Encoding: gzip, deflate/r/n

 

終於解決了。。。還希望有朋友遇到相同的問題少走彎路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章