莫名其妙的 C# HttpWebRequest.GetResponse() 超时错误
2017-03-03 18:03
555 查看
作者:Liigo
日期:20170303
原创链接:http://blog.csdn.net/liigo/article/details/60144144
著作权归作者Liigo所有。商业转载请联系作者获得授权,非商业转载请注明出处。
注意是在访问 “特定URL” 时才超时,访问其他URL是正常的。例如,访问 http://hello.com/?page=2(以下称为page2)超时,而访问 http://hello.com/?page=1 (以下称为page1)和 http://hello.com/?page=3 (以下称为page3)却是正常的。访问page1、page3每次都成功,访问page2每次都超时。
然而page2是可以被浏览器正常访问的;我用易语言两种方法GET请求page2都正常。排除了目标网站不工作或限制访问的情况。
网上有说.Net 3.5 / 4 默认使用代理,加上 HttpWebRequest.Proxy = null; 后也不行。
不是超时设定过短的问题,默认的100秒绝对不短。
我怀疑.Net库有BUG,把 .Net 2.0 换成了.Net 4.5.2、4.6.1,还是不行。
因超时而触发的异常对象只是说超时了,没有更多有价值的参考信息。
网络上找到的下面这篇经典文章,提供了不少解决GetResponse超时问题的办法,但不适用于我现在遇到的状况。
【已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
一定是哪里出了问题!问题是出在哪里?
事实证明还是目标网站的page2有些特殊。经过Fidder观测,发现第一次访问page2时被302重定向到认证页面,进而又被302重定向到page2,我发现必须在访问认证页面时接收Cookie并将其传入到第二次访问page2的请求中。访问page1、page3等其他页面并不需要这一步骤。
上文提到的易语言的两个办法,“
最后的解决办法是,我自行编码跟踪302重定向,接收Cookie并传递给下一个请求。以下是相关C#代码。
日期:20170303
原创链接:http://blog.csdn.net/liigo/article/details/60144144
著作权归作者Liigo所有。商业转载请联系作者获得授权,非商业转载请注明出处。
现象
现象:GET请求 “特定URL” 时超时,无法获取Response响应。代码阻塞在HttpWebRequest.GetResponse()里面。注意是在访问 “特定URL” 时才超时,访问其他URL是正常的。例如,访问 http://hello.com/?page=2(以下称为page2)超时,而访问 http://hello.com/?page=1 (以下称为page1)和 http://hello.com/?page=3 (以下称为page3)却是正常的。访问page1、page3每次都成功,访问page2每次都超时。
然而page2是可以被浏览器正常访问的;我用易语言两种方法GET请求page2都正常。排除了目标网站不工作或限制访问的情况。
分析
我的C#程序启动后第一次请求就是访问page2,排除了Connection、Request、Response等资源耗尽的情况。网上有说.Net 3.5 / 4 默认使用代理,加上 HttpWebRequest.Proxy = null; 后也不行。
不是超时设定过短的问题,默认的100秒绝对不短。
我怀疑.Net库有BUG,把 .Net 2.0 换成了.Net 4.5.2、4.6.1,还是不行。
因超时而触发的异常对象只是说超时了,没有更多有价值的参考信息。
网络上找到的下面这篇经典文章,提供了不少解决GetResponse超时问题的办法,但不适用于我现在遇到的状况。
【已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
一定是哪里出了问题!问题是出在哪里?
解决
问题解决了。事实证明还是目标网站的page2有些特殊。经过Fidder观测,发现第一次访问page2时被302重定向到认证页面,进而又被302重定向到page2,我发现必须在访问认证页面时接收Cookie并将其传入到第二次访问page2的请求中。访问page1、page3等其他页面并不需要这一步骤。
上文提到的易语言的两个办法,“
HTTP读文件()” 和 “
网页_访问_对象()” 都自动处理了Cookie,不需要我关心,自己就工作的很好。可是C#代码的WEB请求并没有帮我接收和传递Cookie,导致最后302重定向很多遍之后以超时告终。
最后的解决办法是,我自行编码跟踪302重定向,接收Cookie并传递给下一个请求。以下是相关C#代码。
// 跟踪302临时跳转,接收Cookies并传递给下一次请求。 // by Liigo 20170303 public static string GetHtmlExX(string strUrl, string strReferer, string strCookies) { try { HttpWebRequest req; HttpWebResponse res = GetHttpWebResponseNoRedirect(strUrl, strReferer, strCookies, out req); while (res.StatusCode == HttpStatusCode.Found) { strUrl = res.Headers[HttpResponseHeader.Location]; strCookies = res.Headers[HttpResponseHeader.SetCookie]; res.Close(); req.Abort(); res = GetHttpWebResponseNoRedirect(strUrl, strReferer, strCookies, out req); } Stream responseStream = res.GetResponseStream(); StreamReader streamReader = new StreamReader(responseStream); string html = streamReader.ReadToEnd(); streamReader.Close(); responseStream.Close(); res.Close(); req.Abort(); return html; } catch (Exception e) { string msg = e.Message; return ""; } } // 执行HTTP GET请求,返回Response对象和Request对象。调用者负责关闭他们:Response.Close(),Request.Abort()。 public static HttpWebResponse GetHttpWebResponseNoRedirect(string strUrl, string strReferer, string strCookies, out HttpWebRequest request) { HttpWebRequest req = null; try { req = HttpWebRequest.Create(strUrl) as HttpWebRequest; if (!string.IsNullOrEmpty(strCookies)) req.Headers[HttpRequestHeader.Cookie] = strCookies; req.ContentType = contentType; req.ServicePoint.ConnectionLimit = maxTry; if (!string.IsNullOrEmpty(strReferer)) req.Referer = strReferer; req.Accept = accept; req.UserAgent = userAgent; req.Method = "GET"; req.Timeout = 15000; req.AllowAutoRedirect = false; HttpWebResponse res = req.GetResponse() as HttpWebResponse; request = req; // Liigo: 如果此处调用req.Abort()关闭请求,则返回的Response对象的数据流是不可读的("流不可读")。 return res; } catch { if (req != null) req.Abort(); request = null; return null; } }
相关文章推荐
- 实现HttpWebRequest.BeginGetResponse的超时控制
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的
- 如何处理C#的HttpWebResponse的GetResponse中的超时异常
- HttpWebRequest的GetResponse或GetRequestStream 超时决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- 已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- 已解决】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- 【转载】HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决