为什么HttpWebResponse会丢失数据?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么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())。在这种情况下,引擎盖下发生了什么?
感谢你付出的努力!
检查int
返回的Stream.Read
,如docs所述:
如果当前没有多个字节可用,则这可能小于请求的字节数,如果已到达流的末尾,则可以小于零(0)。
我愿意打赌在第一次调用中只返回部分流。
如果你反复调用Stream.Read
,你最终会获得所有字节。 http流的加载速度比代码运行的速度慢 - 在调用Read
之前没有时间完成。
通过使用带有CopyTo
的MemoryStream
,调用将阻塞,直到读取整个流。包装在StreamReader
中,然后调用ReadToEnd
将获得相同的成功结果。
以上是关于为什么HttpWebResponse会丢失数据?的主要内容,如果未能解决你的问题,请参考以下文章
使用HttpWebRequest和HttpWebResponse时接收数据中文乱码的情况
c# winform httpWebResponse post出错
C#使用HttpWebRequest发送数据和使用HttpWebResponse接收数据的一个简单示例