Never ending Stream in HttpWebResponse
how can i read some bytes and disconnect? 开发者_开发技巧i use such code
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
using (Stream sm = resp.GetResponseStream())
{
using (StreamReader sr = new StreamReader(sm, Encoding.Default))
{
sr.Read();
sr.Close();
}
}
}
but it wait for end of stream
You probably don't want to use a StreamReader
to read a WebResonse
stream unless you know for sure that the stream contains newlines. StreamReader
likes to think in terms of lines, and if there aren't any newlines in the stream, it's going to hang.
Your best bet is to read as many bytes as you want into a byte[]
buffer, and then convert that to text. For example:
int BYTES_TO_READ = 1000;
var buffer = new byte[BYTES_TO_READ];
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
using (Stream sm = resp.GetResponseStream())
{
int totalBytesRead = 0;
int bytesRead;
do
{
// You have to do this in a loop because there's no guarantee that
// all the bytes you need will be ready when you call.
bytesRead = sm.Read(buffer, totalBytesRead, BYTES_TO_READ-totalBytesRead);
totalBytesRead += bytesRead;
} while (totalBytesRead < BYTES_TO_READ);
// Sometimes WebResponse will hang if you try to close before
// you've read the entire stream. So you can abort the request.
request.Abort();
}
}
At this point, the buffer has the first BYTES_TO_READ
bytes from the buffer. You can then convert that to a string, like this:
string s = Encoding.Default.GetString(buffer);
Or you can open a MemoryStream
on the buffer if you want to use StreamReader
.
I have run into WebResponse
hanging sometimes if you don't read everything. I don't know why it does that, and I can't reliably reproduce it, but I've found that if I do request.Abort()
before closing the stream, everything works. See
On a side note, the word you want is "unresponsive" rather than "unresponsible."
Could you do something like this?
string GetWebPageContent(string url)
{
string result = string.Empty;
HttpWebRequest request;
const int bytesToGet = 1000;
request = WebRequest.Create(url) as HttpWebRequest;
//get first 1000 bytes
request.AddRange(0, bytesToGet - 1);
using (WebResponse response = request.GetResponse())
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
return result;
}
The key is using AddRange in your request.
It is beacuse http 1.1 connection is persistent connection default and the tcp connection has not been closed,so the stream dose not receive the end.
you can use myHttpWebRequest1.KeepAlive=false; so the tcp connection will close after the http reponse.
https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.connection(v=vs.110).aspx#
If you talking winforms or webforms I would put the request into a threadpool (or Task if you are using .net 4). Streams, even with a good handling, are too easy to put GUI in a wait-state that dislikes by most users.
I had similar never-ending request parsing with examples listed here. The following is what I came up with to eliminate those issues:
// url is a string where the request is going.
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
// Do what you have to do with the Request.
StringBuilder builder = new StringBuilder();
int toRead = 1000;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
HttpStatusCode status = response.StatusCode;
using (Stream receiveStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.GetEncoding("utf-8")))
{
Char[] read = new Char[toRead];
int count = readStream.Read(read, 0, toRead);
while (count > 0)
{
string str = new String(read, 0, count);
builder.Append(str);
count = readStream.Read(read, 0, toRead);
}
readStream.Close();
}
}
response.Close();
}
return builder.ToString();
精彩评论