永远不会在HttpWebResponse中结束Stream

问题描述 投票:3回答:5

我怎样才能读取一些字节并断开连接?我使用这样的代码

using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
    using (Stream sm = resp.GetResponseStream())
    {
        using (StreamReader sr = new StreamReader(sm, Encoding.Default))
        {
            sr.Read();
            sr.Close();
        }
    }
}

但它等待流的结束

c# .net httpwebresponse
5个回答
5
投票

您可能不想使用StreamReader来读取WebResonse流,除非您确定该流包含换行符。 StreamReader喜欢用线条来思考,如果流中没有任何换行符,它就会挂起。

最好的办法是在byte[]缓冲区中读取所需的字节数,然后将其转换为文本。例如:

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();
    }
}

此时,缓冲区具有缓冲区中的第一个BYTES_TO_READ字节。然后,您可以将其转换为字符串,如下所示:

string s = Encoding.Default.GetString(buffer);

或者如果你想使用MemoryStream,你可以在缓冲区上打开StreamReader

如果你不读所有内容,我有时会遇到WebResponse。我不知道它为什么这样做,我无法可靠地重现它,但我发现如果我在关闭流之前做request.Abort(),一切正常。看到

另一方面,你想要的词是“反应迟钝”,而不是“不负责任”。


4
投票

你能做这样的事吗?

        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;
        }

关键是在您的请求中使用AddRange


1
投票

它是因为http 1.1连接是持久连接默认而且tcp连接尚未关闭,所以流量不接收结束。

你可以使用myHttpWebRequest1.KeepAlive = false;所以在http响应之后tcp连接将关闭。

https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.connection(v=vs.110).aspx#


0
投票

如果您正在谈论winforms或webforms,我会将请求放入线程池(如果您使用的是.net 4,则为Task)。即使具有良好的处理能力,流也很容易将GUI置于大多数用户不喜欢的等待状态。


0
投票

我有类似的永不停止的请求解析与此处列出的示例。以下是我提出的消除这些问题的方法:

// 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();
© www.soinside.com 2019 - 2024. All rights reserved.