为什么HttpWebResponse会丢失数据?



在另一个问题中,人们在通过GetResponseStream()从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字节。它基本上由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())。在这种情况下到底发生了什么?

谢谢你的努力!

检查Stream.Read返回的int,如文档所述:

如果有那么多字节,则可以小于请求的字节数当前不可用,如果流的末尾有,则为零(0)。

我敢打赌,第一次调用只返回流的一部分。

如果你反复调用Stream.Read,你会得到最后所有的字节。http流加载的速度比代码运行的速度慢——在调用Read之前,它没有时间完成。

通过使用CopyToMemoryStream,调用阻塞,直到整个流被读取。在StreamReader中包装,然后调用ReadToEnd将获得相同的成功结果。

相关内容

  • 没有找到相关文章

最新更新