2016-10-25 4 views
5

또 다른 질문으로 사람들은 GetResponseStream()을 통해 HttpWebResponse에서 읽을 때 불완전한 데이터를 얻고 있습니다.HttpWebResponse가 데이터를 잃는 이유는 무엇입니까?

임베디드 장치에서 데이터를 읽을 때이 문제가 발생했습니다.이 장치는 모든 입력 32 바이트와 64 바이트 * 1000의 구성을 보내야 64032 바이트의 데이터가됩니다.

응답 스트림을 직접 읽는 것만으로 처음 61 개 입력에 대한 데이터 만 가져옵니다.이 입력 데이터는 0부터 시작합니다. 작동하지

버전 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 바이트를 출력한다. 기본적으로 40 개의 ascii 문자와 부울 및 정수 값을 나타내는 몇 바이트로 구성됩니다.

버전 A) 출력 : 나는 새로운 MemoryStream을에 ResponseStream을 복사 할 때

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

, 나는 완전히 어떤 손상 바이트 않고 모든 1000 개 입력을 읽을 수 있습니다.

(또한 기술에서 첫 번째 경우에서 내 문제)

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 

을 고정 https://stackoverflow.com/a/22354617/6290907을 참조하십시오 완벽하게 작동

버전 B) 관점 : HttpWebResponse가 데이터에 직접 액세스 할 때 데이터를 잃는 이유는 무엇입니까? 나는 단지 작동시키기를 원하지 않지만, 버전 a가 실패한 이유와 버전 b가 성공한 이유를 모두 이해하고 싶습니다. 둘 다 동일한 소스 (response.GetResponseStream())에 의존하고 있습니다. 이 경우에는 어떤 일이 발생합니까?

감사합니다.

답변

2

intdocs에 의해 설명 된 바와 같이, Stream.Read에 의해 반환 된 체크 : 많은 바이트 현재 사용할 수없는 경우

이 요청한 바이트 수보다 적을 수 있습니다, 또는 제로 (0)의 경우 스트림의 끝 부분에 에 도달했습니다.

첫 번째 호출에서 스트림의 일부만 반환됩니다.

Stream.Read을 반복적으로 호출하면 결국 모든 바이트를 가져옵니다. http 스트림은 코드가 실행되는 것보다 느리게로드됩니다. Read에 전화하기 전에 완료 할 시간이 없습니다.

MemoryStream을 사용하여 CopyTo을 사용하면 전체 스트림을 읽을 때까지 호출이 차단됩니다.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

관련 문제