HttpWebRequest請求http1.1的chunked的解析問題記錄

weixin_34119545發表於2017-03-18

問題:我的請求獲取不到URL對應的內容(換個瀏覽器可以)。

 

第一步對比wirshark截包看HTTP請求頭,發現我這缺失一部分請求頭。

對著官方文件新增即可。https://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest(v=vs.110).aspx

第二步,校正請求頭後請求後,發現wireshark有返回,但是無法獲取。debug發現無法解析內容。

這個地方可能會耗費一點時間和經驗才能知道。

經過目測,發現這個網站是HTTP1.1 ,還有一個引數chunked。簡單說就是返回內容的時候,分段返回的。不設定長度。

老版本的讀取方法的話,對於這種是沒法讀取的。參考另一個網友的辦法就解決了。

供大家參考吧。自己專案程式碼就不貼了,避嫌。

static void Main(string[] args)
        {
            HttpWebResponse web = MySpider.GetResponse("http://localhost:1853/WebForm1.aspx");
            DecompressGZip(web );
            Console.ReadLine();
        }
 
public static MemoryStream DecompressGZip(HttpWebResponse res)
    {

  

 //如果伺服器使用了Transfer-Encoding:chunked緩衝輸出,則只要伺服器端Flush了,就會觸發此方法,而不是等到伺服器傳送過來的內容全部傳送完才觸發,
//而且與是不是非同步HttpWebRequest請求也沒有關係。相反,如果伺服器沒有使用Transfer-Encoding:chunked緩衝輸出,
//則不管是非同步HttpWebRequest請求還是同步HttpWebRequest請求,都得等到伺服器傳送過來的內容全部傳送完才觸發此方法。
Stream stream = res.GetResponseStream(); int length = 0; if (res.ContentLength > 0) { length = (int)res.ContentLength; } else { length = 3000; } MemoryStream memory = new MemoryStream(length); int count = 0; //每次從伺服器返回流中讀取5000個位元組 byte[] buffer = new byte[5000]; while (true) {        //如果伺服器使用了Transfer-Encoding:chunked緩衝輸出,則如果已經讀取了伺服器第一次Flush的內容後伺服器第二次Flush的內容還沒有接收到,則會阻塞當前執行緒,
//直到接收到伺服器第二次Flush的內容(第三,四。。。次Flush也是一樣),所以很可能會造成讀取一次返回的count不滿5000,但下一次繼續讀取返回的count卻不是0的情況
count = stream.Read(buffer, 0, buffer.Length); if (count == 0) { break; } memory.Write(buffer, 0, count); } stream.Close(); //將流的可讀位置設定到起始值 memory.Seek(0, SeekOrigin.Begin); return memory; }

 

 

 

 

附錄

相關文章