2016-10-25 36 views
5

Trong một câu hỏi khác, mọi người đang nhận được dữ liệu không đầy đủ khi đọc từ một HttpWebResponse qua GetResponseStream().Tại sao HttpWebResponse mất dữ liệu?

Tôi cũng gặp phải sự cố này khi đọc dữ liệu từ thiết bị được nhúng sẽ gửi cho tôi cấu hình 1000 đầu vào, tất cả trong tất cả 32 byte tiêu đề và 64 byte * 1000 dẫn đến 64032 byte dữ liệu.

Đọc luồng phản hồi trực tiếp chỉ cung cấp cho tôi dữ liệu cho đầu vào 61 đầu tiên và một nửa, từ đó chỉ trên số không.

Version a) Không làm việc:

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; 

Để hình dung được vấn đề, tôi in 64 byte cho mỗi cấu hình đầu vào riêng rẽ. Nó bao gồm cơ bản của 40 ký tự ascii và một vài byte đại diện cho giá trị boolean và số nguyên.

Version A) Output:

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

Khi tôi sao chép ResponseStream đến một MemoryStream mới, tôi có thể đọc tất cả 1000 đầu vào hoàn toàn mà không cần bất kỳ byte tham nhũng.

Version B) Làm việc một cách hoàn hảo:

(Xem thêm https://stackoverflow.com/a/22354617/6290907 mà cố định vấn đề của tôi trong trường hợp đầu tiên)

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; 

Version B) Output

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

Từ một kỹ thuật quan điểm: Tại sao HttpWebResponse mất dữ liệu khi được truy cập trực tiếp? Tôi không chỉ muốn nó hoạt động, nhưng tôi muốn hiểu tại sao phiên bản thất bại và phiên bản b thành công trong khi cả hai đều phụ thuộc vào cùng một nguồn dữ liệu (response.GetResponseStream()). Điều gì đang xảy ra dưới mui xe trong trường hợp này?

Cảm ơn bạn đã nỗ lực!

Trả lời

2

Kiểm tra các int trả về bởi Stream.Read, như mô tả của các docs:

Điều này có thể ít hơn số lượng các byte yêu cầu nếu mà nhiều byte hiện không có sẵn, hoặc không (0) nếu cuối luồng đã đạt được .

Tôi sẵn sàng đặt cược rằng chỉ một phần của luồng được trả lại trong cuộc gọi đầu tiên.

Nếu bạn gọi Stream.Read nhiều lần, bạn sẽ nhận được tất cả các byte cuối cùng. Luồng http chỉ đơn giản tải chậm hơn mã của bạn đang chạy - nó không có thời gian để hoàn thành trước khi bạn gọi Read.

Bằng cách sử dụng CopyTo với MemoryStream, khối cuộc gọi cho đến khi toàn bộ luồng được đọc.Gói trong số StreamReader, sau đó gọi ReadToEnd sẽ nhận được kết quả tương tự thành công.

+0

int bytesRead = 0; int bytesToRead = buffer.Length; do { int n = s.Read (bộ đệm, bytesRead, bytesToRead); bytesĐọc + = n; bytesToRead - = n; } trong khi (bytesToRead! = 0); –

+0

Điều đó đã làm được điều đó! Tôi khá mới mẻ với thế giới nhúng và đã làm việc với văn bản chỉ trước đây, vì vậy tôi đã bỏ lỡ số lượng byte được đọc khi không sử dụng StreamReader dựa trên văn bản. Cảm ơn bạn rất nhiều! –

+0

@ManuelR: Bạn được chào đón nhiều nhất! – Baldrick

Các vấn đề liên quan