HttpWebRequest 引发不同的 WebExceptionStatus

您所在的位置:网站首页 连接超时10060 HttpWebRequest 引发不同的 WebExceptionStatus

HttpWebRequest 引发不同的 WebExceptionStatus

2023-08-15 20:57| 来源: 网络整理| 查看: 265

System.Net.HttpWebRequest 在特殊条件下为 SSL 和非 SSL 请求引发不同的 WebExceptionStatus 项目 07/17/2023

本文可帮助你解决在使用 System.Net.HttpWebRequest 类时引发不同的WebExceptionStatus问题。

原始产品版本: .Net Framework 原始 KB 编号: 2007873

症状

使用 System.Net.HttpWebRequest Microsoft .Net Framework 的 类将超文本传输协议 (HTTP) 或超文本传输协议安全 (HTTPS) 请求发送到服务器。 此请求需要一些时间来接收来自服务器的响应。 在此等待时间内,如果手动增加系统时钟时间,或者系统时钟滞后,然后 Windows 时间服务调整到实际本地时间,则会遇到以下情况之一:

对于通过纯文本 HTTP 发送的请求, System.Net.HttpWebRequest 类将引发以下异常:

请求已中止:操作已超时。

此外, Status 引发 WebException 的 上的 属性将指示值 WebExceptionStatus.Timeout。

对于通过 HTTPS 发送的请求, System.Net.HttpWebRequest 类将引发以下异常之一:

基础连接已关闭:接收时发生意外错误。

此外, Status 引发 WebException 的 上的 属性将指示值 WebExceptionStatus.ReceiveFailure。

基础连接已关闭:服务器关闭了预期保持活动状态的连接。

此外, Status 引发 WebException 的 上的 属性将指示值 WebExceptionStatus.KeepAliveFailure。

在上述所有方案中, 捕获的 具有 InnerException 属性。 如果捕获 WebException 并引用 属性 WebException.InnerException.InnerException ,你会注意到,对于上述所有情况, Message 字符串将指示:

连接尝试失败,因为连接方在一段时间后没有正确响应,或者由于连接的主机无法响应而建立连接失败。

此消息是 Winsock 错误代码 10060 = WSAETIMEDOUT 的详细解释。

因此,当手动增加系统时间时,Winsock 会正确引发超时错误 10060,但安全套接字层 (SSL) 和非 SSL 请求的不同异常类型会被包装。

在系统时间未篡改的正常超时情况下,SSL 和非 SSL 方案将正确反映 WebExceptionStatus.Timeout 状态并引发常见异常: 操作已超时。

原因

通过 SSL 或非 SSL 发出请求时, System.Net.ServicePointManager 类会将请求分配给内部连接,该连接最终将建立 Winsock 连接。 对于 SSL 请求,此请求或连接通过另一个内部 SSL/TLS 类,该类负责加密或解密数据。 对于非 SSL 连接,根本不涉及此内部 SSL/TLS 类。

修改时间并在 Winsock 层遇到异常时,此错误现在需要从 Winsock 向上传播到应用层。 对于非 SSL 连接,内部连接类直接捕获此异常,但对于 SSL 请求,此错误由内部 SSL/TLS 类处理。 此类将此非 SSL 错误视为 ReceiveFailure 或 KeepAliveFailure ,因此具有不同的异常状态,而对于非 SSL 连接,错误被正确强制转换,因为它由其他类处理。

状态

此行为是设计使然。

解决方案

为了解决在此特殊情况下引发的异常类型的这种差异,其中系统时间被篡改,应用程序需要捕获 WebException ,然后引用 属性 WebException.InnerException.InnerException.Message 。

Message如果字符串等于等效于 10060 = WSAETIMEDOUT 的 winsock 详细错误,则可以将 ReceiveFailure 或 KeepAliveFailure 视为常规超时,而不将其视为 ReceiveFailure 或 KeepAliveFailure。

对于框架的英语版本,应用程序可以在执行 catch() 的 WebException 时使用以下解决方法。 对于框架的本地化版本,需要根据语言本地化调整以下解决方法。

重要

此示例代码按原样提供,仅用于示例目的。 不提供任何保证,也不授予任何权利。

try { ...... } catch (WebException oWEx) { WebExceptionStatus oStatus = oWEx.Status; String strTimeoutErrorMessage = "A connection attempt failed because the connected party did not properly respond " + "after a period of time, or established connection failed because connected host has failed to respond"; switch (oStatus) { case WebExceptionStatus.KeepAliveFailure: if ((oWEx.InnerException != null) && (oWEx.InnerException.InnerException != null) && oWEx.InnerException.InnerException.Message.ToString().Equals(strTimeoutErrorMessage, StringComparison.CurrentCultureIgnoreCase)) { //---------------------------------------------------------------------- // This is Timeout Error which is wrongly thrown as a ReceiveFailure for // SSL requests under this special condition. // // Handle this as a Timeout Error //---------------------------------------------------------------------- } else { //---------------------------------------------------------------------- // This is truly a KeepAliveFailure. //---------------------------------------------------------------------- } break; case WebExceptionStatus.Timeout: //---------------------------------------------------------------------- // This is a Timeout. //---------------------------------------------------------------------- break; case WebExceptionStatus.ReceiveFailure: if ((oWEx.InnerException != null) && (oWEx.InnerException.InnerException != null) && oWEx.InnerException.InnerException.Message.ToString ().Equals (strTimeoutErrorMessage, StringComparison.CurrentCultureIgnoreCase)) { //---------------------------------------------------------------------- // This is Timeout Error which is wrongly thrown as a ReceiveFailure for // SSL requests under this special condition. // // Handle this as a Timeout Error //---------------------------------------------------------------------- } else { //---------------------------------------------------------------------- // This is truly a ReceiveFailure. //---------------------------------------------------------------------- } break; default: //---------------------------------------------------------------------- // This is some other Exception //---------------------------------------------------------------------- break; } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3