为什么 HttpWebResponse 会丢失数据?
Why is HttpWebResponse losing data?
在另一个问题中,人们在通过 GetResponseStream() 从 HttpWebResponse 读取数据时得到的数据不完整。
我在从嵌入式设备读取数据时也遇到了这个问题,该设备应该向我发送 1000 个输入的配置,总共 32 个字节 header 和 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) 完美运行:
(另请参阅 ,它解决了我在第一种情况下的问题)
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
,如 docs 所述:
This can be less than the number of bytes requested if that many bytes
are not currently available, or zero (0) if the end of the stream has
been reached.
我敢打赌,在第一次调用中只返回了部分流。
如果您重复调用 Stream.Read
,您将在最后获得所有字节。 http 流的加载速度比您的代码慢 运行 - 在您调用 Read
.
之前它没有时间完成
通过将 CopyTo
与 MemoryStream
结合使用,调用会阻塞,直到读取整个流。包装在 StreamReader
中,然后调用 ReadToEnd
将获得相同的成功结果。
在另一个问题中,人们在通过 GetResponseStream() 从 HttpWebResponse 读取数据时得到的数据不完整。
我在从嵌入式设备读取数据时也遇到了这个问题,该设备应该向我发送 1000 个输入的配置,总共 32 个字节 header 和 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) 完美运行:
(另请参阅 ,它解决了我在第一种情况下的问题)
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
,如 docs 所述:
This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
我敢打赌,在第一次调用中只返回了部分流。
如果您重复调用 Stream.Read
,您将在最后获得所有字节。 http 流的加载速度比您的代码慢 运行 - 在您调用 Read
.
通过将 CopyTo
与 MemoryStream
结合使用,调用会阻塞,直到读取整个流。包装在 StreamReader
中,然后调用 ReadToEnd
将获得相同的成功结果。