문제

StreamReader를 사용하여 HttpWebResponse의 GetResponseStream()에서 반환된 스트림을 읽을 때 "청크된" 응답을 읽는 데 문제가 있습니다.

// response is an HttpWebResponse
StreamReader reader = new StreamReader(response.GetResponseStream());
string output = reader.ReadToEnd(); // throws exception...

reader.ReadToEnd() 메서드가 호출되면 다음 System.IO.IOException이 발생합니다. 전송 연결에서 데이터를 읽을 수 없습니다.연결이 종료되었습니다.

위 코드는 서버가 "청크되지 않은" 응답을 반환할 때 제대로 작동합니다.

내가 작동하게 할 수 있었던 유일한 방법은 초기 요청에 HTTP/1.0을 사용하는 것이었지만(기본값인 HTTP/1.1 대신) 이것은 형편없는 해결 방법처럼 보입니다.

어떤 아이디어가 있나요?


@척

귀하의 솔루션은 꽤 잘 작동합니다.마지막 Read()에서 여전히 동일한 IOExeception이 발생합니다.그러나 StringBuilder의 내용을 검사한 후에는 모든 데이터가 수신된 것처럼 보입니다.그래서 아마도 Read()를 try-catch로 래핑하고 "오류"를 삼켜야 할 것입니다.

도움이 되었습니까?

해결책

"청크" 응답으로 이것을 시도하지 않았지만 이와 같은 것이 작동할까요?

StringBuilder sb = new StringBuilder();
Byte[] buf = new byte[8192];
Stream resStream = response.GetResponseStream();
string tmpString = null;
int count = 0;
do
{
     count = resStream.Read(buf, 0, buf.Length);
     if(count != 0)
     {
          tmpString = Encoding.ASCII.GetString(buf, 0, count);
          sb.Append(tmpString);
     }
}while (count > 0);

다른 팁

비슷한 문제를 해결하고 있습니다..net HttpWebRequest 및 HttpWebRequest는 쿠키를 처리하고 자동으로 리디렉션하지만 응답 본문의 청크된 콘텐츠는 자동으로 처리하지 않습니다.

이는 아마도 청크된 콘텐츠에 단순한 데이터 이상의 내용이 포함될 수 있기 때문일 수 있습니다(예:청크 이름, 후행 헤더).

단순히 스트림을 읽고 EOF 예외를 무시하는 것은 스트림에 원하는 콘텐츠보다 많은 내용이 포함되어 있기 때문에 작동하지 않습니다.스트림에는 청크가 포함되며 각 청크는 크기를 선언하여 시작됩니다.스트림을 처음부터 끝까지 단순히 읽는 경우 최종 데이터에는 청크 메타데이터가 포함됩니다(그리고 콘텐츠가 gzip으로 압축된 경우 압축을 풀 때 CRC 검사에 실패합니다).

문제를 해결하려면 스트림을 수동으로 구문 분석하고 각 청크(CR LF 구분 기호 포함)에서 청크 크기를 제거하고 최종 청크를 감지하고 청크 데이터만 유지해야 합니다.아마도 어딘가에 이 작업을 수행하는 라이브러리가 있을 것입니다. 아직 찾지 못했습니다.

유용한 자료:

http://en.wikipedia.org/wiki/Chunked_transfer_encoding http://tools.ietf.org/html/rfc2616#section-3.6.1

Craig, 읽고 있는 스트림을 보지 않고는 디버깅하기가 조금 어렵지만 count 변수의 설정을 다음과 같이 변경할 수 있습니다.

count = resStream.Read(buf, 0, buf.Length-1);

약간의 해킹이지만 마지막 읽기로 인해 문제가 발생하고 데이터가 반환되지 않으면 이론적으로 문제를 피할 수 있습니다.스트림이 왜 그렇게되는지 아직도 궁금합니다.

나는 같은 문제를 겪었습니다 (이것이 내가 여기까지 온 방법입니다 :-).결국 청크된 스트림이 유효하지 않다는 사실까지 추적했습니다. 마지막 0 길이 청크가 누락되었습니다.유효한 청크 스트림과 유효하지 않은 청크 스트림을 모두 처리하는 다음 코드를 생각해 냈습니다.

using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
    StringBuilder sb = new StringBuilder();

    try
    {
        while (!sr.EndOfStream)
        {
            sb.Append((char)sr.Read());
        }
    }
    catch (System.IO.IOException)
    { }

    string content = sb.ToString();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top