2016-10-25 53 views
5

另一個問題是,通過GetResponseStream()從HttpWebResponse中讀取數據時,人們的數據不完整。HttpWebResponse爲什麼會丟失數據?

從嵌入式設備讀取數據時,我也遇到了這個問題,它應該向我發送1000個輸入的配置,全部是32字節的標題,64字節* 1000導致64032字節的數據。

直接讀取響應流僅爲第一個61和一半的輸入提供數據,從那裏只有零。

版a)不工作:

int headerSize = 32; 
int inputSize = 64; 
byte[] buffer = new byte[(inputSize*1000) + headerSize]; 

HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

using (Stream stream = response.GetResponseStream()) 
{ 
    if (stream != null) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     stream.Read(buffer, 0, buffer.Length); 
    } 
} 

response.Close(); 
return buffer; 

爲了顯現問題,我打印的64個字節用於每個輸入配置seperately。它基本上由40個ASCII字符和幾個表示布爾值和整數值的字節組成。

版A)輸出:

1/1000 | 46656E7374657220576F686E656E2020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100090010020 
2/1000 | 42574D20576F686E656E202020202020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100091010080 
… 
61/1000 | 53656E736F72203631202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
62/1000 | 53656E736F7220363220202020202020202020202020202020202020202020200000000000000000000000000000000000000000000000000000000000000000 
63/1000 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
… 
999/1000 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
1000/1000 | 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

當我ResponseStream複製到一個新的MemoryStream,我可以讀取所有1000個輸入完全沒有任何損壞的字節。

版B)正常使用:

(參見https://stackoverflow.com/a/22354617/6290907其中固定資產我在第一種情況下的問題)

int headerSize = 32; 
int inputSize = 64; 
byte[] buffer = new byte[(inputSize*1000) + headerSize]; 

HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

using (Stream stream = response.GetResponseStream()) 
{ 
    if (stream != null) 
    { 
     MemoryStream memStream = new MemoryStream(); 
     stream.CopyTo(memStream); 
     memStream.Flush(); 
     stream.Close(); 

     memStream.Seek(0, SeekOrigin.Begin); 
     memStream.Read(buffer, 0, buffer.Length); 

     memStream.Close(); 
    } 
} 

response.Close(); 
return buffer; 

版B)輸出

1/1000 | 46656E7374657220576F686E656E2020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100090010020 
2/1000 | 42574D20576F686E656E202020202020202020202020202020202020202020202020202020202020000000000F0EB0AA00008100000001800000100091010080 
… 
61/1000 | 53656E736F72203631202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
62/1000 | 53656E736F72203632202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
63/1000 | 53656E736F72203633202020202020202020202020202020202020202020202020202020202020200000000000000000000010003300000000001000C3010000 
… 
999/1000 | 53656E736F7220393939202020202020202020202020202020202020202020202020202020202020000000000000000000001000DA030000000010006A050000 
1000/1000 | 53656E736F7220313030302020202020202020202020202020202020202020202020202020202020000000000000000000001000DB030000000010006B050000 

從技術觀點:爲什麼HttpWebResponse直接訪問時會丟失數據? 我不只是想讓它工作,但我想了解爲什麼版本a失敗,版本b是成功的,而兩者都依賴於相同的數據源(response.GetResponseStream())。 在這種情況下引擎蓋下發生了什麼?

謝謝你的努力!

回答

2

檢查int通過Stream.Read返回,如由docs描述:

這可以是小於要求的字節數,如果很多字節 當前不可用,或零(0),如果流的末尾已達到 。

我敢打賭,只有部分流是在第一次調用中返回的。

如果你反覆調用Stream.Read,你會得到所有的字節。 http流的加載速度比您的代碼運行速度慢 - 在您致電Read之前,沒有時間完成。

通過使用CopyToMemoryStream,呼叫阻塞,直到讀取整個流。包裝在StreamReader中,則調用ReadToEnd將獲得相同的成功結果。

+0

int bytesRead = 0; int bytesToRead = buffer.Length; do int n = s.Read(buffer,bytesRead,bytesToRead); bytesRead + = n; bytesToRead - = n; } while(bytesToRead!= 0); –

+0

這個伎倆!我對嵌入式世界非常陌生,之前只使用文本,所以我錯過了在不使用基於文本的StreamReader時讀取的字節數。 非常感謝! –

+0

@ManuelR:你很受歡迎! – Baldrick