如何在向某些站点发出 HttpWebRequest 时修复“底层连接已关闭:连接已意外关闭”
Posted
技术标签:
【中文标题】如何在向某些站点发出 HttpWebRequest 时修复“底层连接已关闭:连接已意外关闭”【英文标题】:How to fix "The underlying connection was closed: The connection was closed unexpectedly" when making a HttpWebRequest to certain sites 【发布时间】:2019-02-04 02:58:22 【问题描述】:我无法收到来自https://www.adidas.ca 等某些网站的回复,但联系https://www.google.ca 没有问题。
我尝试了以下方法: 1。设置 SecurityProtocol = SecurityProtocolType.Tls |安全协议类型.Tls11 |安全协议类型.Tls12 |安全协议类型.Ssl3; 2。设置 KeepAlive = true; 3。设置适当的标头,例如 UserAgent、Accept-Encoding 和 Accept-Language。 4。使用 Fiddler 和 Post-Man 查看我手动发出的请求的差异,并从代码中查看可能有什么不同(我找不到任何东西)。
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 |
SecurityProtocolType.Ssl3;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.adidas.com/");
request.KeepAlive = true;
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (Khtml, like Gecko) Chrome/71.0.3578.98 Safari/537.36";
request.Headers.Add("Accept-Encoding", "identity;q=1, *;q=0");
request.Headers.Add("Accept-Language", "en-US,en;q=0.5");
request.Method = "GET";
request.Accept = "*/*";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
我希望收到 200 响应,就像我从 https://www.google.ca/ 收到的一样,但收到了一个错误: System.Net.WebException: '底层连接已关闭:连接意外关闭。'
【问题讨论】:
使用像wireshark或fiddler这样的嗅探器。比较使用浏览器手动访问站点与使用 C# 应用程序的结果。比较 http 标头,让您的应用看起来像浏览器结果。 @jdweng 我已经尝试过使用 fiddler 并尝试尽可能地复制请求标头,但结果相同。我可能错过了什么,我会再试一次。 HTTP 使用 TCP 作为传输层。 TCP 最大大小约为 1500 字节,因此每个 HTTP 消息可以包含一个或多个 TCP 数据报。嗅探器显示 TCP 和组合的 HTTP 消息。如果连接关闭,那么您会在其中一个 TCP 数据报中看到一个 FIN。 @jdweng 我很抱歉,因为我不精通网络/并没有真正理解您要解释的内容,但是您能否详细说明这与我的问题有何关系?您是说我无法连接的网站在尝试向其发出请求时故意向我发送 FIN? 【参考方案1】:我能够通过使用 fiddler 并启用 解密 HTTPS 流量 选项来解决该问题,这样我就可以看到正在发出的请求并将其转换为 C# 代码。
【讨论】:
您对请求的具体更改是什么?以上是关于如何在向某些站点发出 HttpWebRequest 时修复“底层连接已关闭:连接已意外关闭”的主要内容,如果未能解决你的问题,请参考以下文章
向数百个站点发出 curl 请求是不是会被某些主机视为攻击?