2016-10-25 6 views
5

В другом вопросе люди получают неполные данные при чтении из HttpWebResponse через GetResponseStream().Почему HttpWebResponse теряет данные?

Я тоже столкнулся с этой проблемой при чтении данных с встроенного устройства, которое должно отправить мне конфигурацию из 1000 входов, всего 32 байта и 64 байта * 1000, что приводит к 64032 байтам данных.

Чтение потока ответов непосредственно дает мне данные только для первых 61 с половиной входов, оттуда только нули.

вариант а) Не работает:

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 байта для каждой конфигурации входа отдельно. Он состоит в основном из 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 теряет данные при непосредственном доступе? Я не просто хочу, чтобы это сработало, но я хочу понять, почему версия с ошибкой и версия b успешна, в то время как оба зависят от одного и того же источника данных (response.GetResponseStream()). Что происходит под капотом в этом случае?

Спасибо за ваши усилия!

ответ

2

Проверьте int возвращаемый Stream.Read, как описано docs:

Это может быть меньше, чем количество байт, запрошенных если что много байт в настоящее время не имеется, или ноль (0), если конец потока достигнут .

Я готов поспорить, что только часть потока возвращается при первом вызове.

Если вы повторно вызвали Stream.Read, вы получите все байты в конце. HTTP-поток просто загружается медленнее, чем ваш код работает - у него нет времени для завершения, прежде чем вы вызовете Read.

С помощью CopyTo с номером MemoryStream блокировки вызовов до тех пор, пока не будет прочитан весь поток.Обертка в 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

Смежные вопросы