我与服务器端有HTTP连接,使用System.IO.Stream.Read读取HTTP消息。问题是,一旦在几分钟内,服务器就会卡在Read语句上,并且在到达套接字超时或客户端关闭连接之前不会继续。
int bytesRead = 0;
while (bytesRead < contentLength)
{
int got = stream.Stream.Read(buffer.Buffer, bytesRead, contentLength - bytesRead);
bytesRead += got;
}
为什么它会被卡住而不继续读取数据?
发布于 2011-09-19 06:27:33
这似乎与以下事实有关:我使用的是NetworkStream的Read方法(这是上面代码中看到的调用)和通过将NetworkStream对象传递给它的构造函数创建的StreamReader。
NetworkStream.Read用于读取http请求消息体,而StreamReader.Read用于读取请求的其余部分(起始行、标头.)。虽然调用是由同一个线程同步进行的,但这可能是我所经历的行为的原因。
当将代码更改为只使用套接字并直接从套接字执行读取时,它解决了这个问题。
发布于 2011-09-15 08:10:03
我想知道流是否报告提前终止;您还应该查看Read
是否返回了一个非正数,即
while (bytesRead < contentLength)
{
int got = stream.Stream.Read(
buffer.Buffer, bytesRead, contentLength - bytesRead);
if(got <= 0) throw new EndOfStreamException(string.Format(
"Expected {0} bytes; {1} bytes received", contentLength, bytesRead));
bytesRead += got;
}
基本上,如果流已经关闭,对Read
的每个调用都将返回非正(可能为0),因此您的while
循环将成为"read 0,add 0,read 0,add 0“的紧密循环。
作为最后一点,您的方法建议您根据传入的内容长度标头分配一个byte[]
;只是一个警告:确保您的理智-检查它并将其限制在正常值,否则一个DOS攻击是微不足道的。此外,如果可能的话,我建议在可能的情况下尝试使用流API,以避免将其同时加载到内存中(除非您限制了传入的大小,这样就不需要担心了)。
发布于 2011-09-15 08:12:42
尝试这个实现,您的计数(contentLength - bytesRead)是错误的。应该是缓冲区大小。
byte[] buffer = new byte[bufferSize];
int count;
while ((count = stream.Stream.Read(buffer, 0, buffer.Length)) != 0)
{
// do something with the buffer using count as the end marker
destination.Write(buffer, 0, count);
}
如果您只想从流中得到一个字节数组,这更像是您正在尝试的:
byte[] buffer = stream.Stream.ToArray()
或复制到另一个缓冲区:
byte[] data = stream.Stream.ToArray();
Array.CopyTo(data , buffer.Buffer, data.Length)
https://stackoverflow.com/questions/7427611
复制相似问题