【问题标题】:System.Net.WebException: The underlying connection was closed: An existing connection was forcibly closed by the remote hostSystem.Net.WebException:底层连接已关闭:现有连接被远程主机强行关闭
【发布时间】:2018-03-23 13:52:00
【问题描述】:

我已经看到了一些其他线程,但还没有找到解决方案。从调试模式运行我的 C# Windows 时,我可以使用 WebClient 从网页读取数据。但是,一旦我为应用程序创建了可执行文件,我就无法从网页中读取数据。这是我得到的例外:

System.Net.WebException:底层连接已关闭:发送时发生意外错误。 ---> System.IO.IOException: Unable to read data from the transport connection: 一个现有的连接被远程主机强行关闭。 ---> System.Net.Sockets.SocketException:现有连接被远程主机强行关闭 在 System.Net.Sockets.Socket.Receive(Byte[] 缓冲区,Int32 偏移量,Int32 大小,SocketFlags socketFlags) 在 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小)

---内部异常堆栈跟踪结束---

这是我正在使用的代码的 sn-p:

WebClient webClient = new WebClient();
webClient.UseDefaultCredentials = true;
webClient.Proxy.Credentials = CredentialCache.DefaultCredentials;
webClient.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
string page = webClient.DownloadString(webPath + manPartNum);

就像我之前说的,我可以让它在 Visual Studio 的调试模式下正常工作,但是一旦我创建了可执行文件,我就无法再从网页中读取。任何帮助,将不胜感激。什么可能导致此问题?

【问题讨论】:

  • 可能性很小。 1)由于编译器的依赖性问题,您所做的所有更改都没有进入可执行文件。所以你可以删除 bin 文件夹,它将完全重建项目,这样发布模式将得到重建 2)代码第一次工作。但是第二次建立 cookie 并且使用 cookie 运行代码有问题。所以你可以打开一个IE 并删除包括 cookie 在内的历史记录,然后重试。或者返回调试版本,看看它是否仍然有效。3)您的旧连接未关闭,服务器不允许来自同一 IP 地址的多个连接。
  • UseDefaultCredentials 和您提供的当前用户凭据不会冲突吗?当您在调试中“成功”时,我会查看输出窗口,以确保它不会也扔在那里,但无论如何让您侥幸逃脱。
  • 感谢您的快速回复。我试过你的建议。 1)我删除了bin文件夹并完全重建了项目。没有成功。 2)我在调试模式下重新运行了程序,它在调试模式下仍然可以正常工作。 3)有没有办法让我关闭网络客户端? webclient.Close()?
  • @DonBoitnott - 你就是男人!谢谢你的帮助。那是我的问题。我删除了两行默认凭据,它现在可以工作了。
  • 我兴奋得太早了。看来这个问题是间歇性的。它在我的机器上运行,但是当我在另一台机器上使用可执行文件时,它出现了与我之前看到的相同的错误。

标签: c# .net winforms wcf webclient


【解决方案1】:

另一种方法是使用HttpWebRequest

String responseFromServer = null;
var url = webPath + manPartNum;
var request = (HttpWebRequest)HttpWebRequest.Create(urlPing);
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";
var response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
    using (var dataStream = response.GetResponseStream())
    {
        using (var reader = new StreamReader(dataStream))
            responseFromServer = reader.ReadToEnd();
    }
}

if (!String.IsNullOrEmpty(responseFromServer))
{
}

除非您真正“登录”到该页面,否则您可能没有必要使用WebClient。如果您只需要请求页面响应,那么这应该可以避免所有这些身份验证问题。

【讨论】:

  • 再次感谢。但是,我在使用 HttpWebRequest 时遇到与使用 WebClient 时相同的错误。我认为我的问题与我尝试访问的网站有关。例如,我可以访问一个分销商网站,但不能访问另一个。该网站似乎认识到我的应用程序是一个机器人。
  • @TylerWilson 那也许它通过频率限制了类似的连接。您看到的间歇性模式可能是因为您尝试将它们靠得太近而它不喜欢那样。 DDoS 预防等。
  • 有没有办法绕过这个 DDoS 防护?这显然是有原因的。在我的代码中添加延迟会允许这样做吗?
  • 只有知道您所追求的网站的人才能回答这个问题。如果有,它可能需要登录,以便网站知道您是谁/什么。否则,您只是另一个潜在的攻击者。
【解决方案2】:

经过更多研究,我能够确定我尝试访问的网站具有 OAuth 2.0 身份验证和授权。看来我必须在公司注册并使用他们的 API 通过我的应用程序访问他们的网站。希望这对其他人有帮助。

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 2021-05-12
    相关资源
    最近更新 更多