C# .Net FrameWork3.5中异步HTTP请求时,由于安全协议的问题System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)方法抛出“基础连接已经关闭: 发送时发生错误”的解决办法
现象描述:
C# .Net FrameWork3.5中异步HTTP请求时,由于安全协议的问题System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)方法抛出“基础连接已经关闭: 发送时发生错误”。
原因分析:
大多数情况下是由于客户端所设置的HTTP访问请求的安全协议不符合服务器端的安全协议要求。比如,NASA提供瓦片服务的http://worldwind25.arc.nasa.gov/wms?service=WMS&version=1.3.0&request=GetMap&layers=esat&styles=default&crs=CRS:84&bbox=0,-54,36,-18&width=512&height=512&format=image/jpeg&transparent=true&bgcolor=0x000000链接,服务器端要求TSL1.2安全协议,而我所使用的C# .Net FrameWork3.5中只支持Ssl3和Tls1.0两种协议,因此造成上述异常。
解决办法:
方法1、将开发环境Visual C#2008的 .Net FrameWork3.5框架升级为Visual C#2012的 .Net FrameWork4.5或更高版本,并将安全协议设置为:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
方法2、不升级开发框架。而是对操作系统和开发环境打补丁。步骤如下:
(1)我的开发环境为Windows7 64为操作系统+Visual C#2008的 .Net FrameWork3.5。去微软官网下载专用的补丁包。注意区分32位或64位。如下图所示。
(2)安装操作系统补丁包。直接安装可能无法进行,可按照如下的步骤安装:
1)将安装包windows6.1-kb3154518-x64.msu拷贝到一指定位置,如D:\update\目录下。
2)管理员身份打开命令提示符cmd.exe。
3)切换到到指定的目录中,然后分别执行下面两句命令:
expand –F:* D:\update\windows6.1-kb3154518-x64.msu D:\update\ dism.exe /online /Add-Package /PackagePath:D:\update\Windows6.1-KB3154518-x64.cab
(3)向操作系统的注册表添加以下两个值(对于 64 位操作系统)。
在[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]下面添加:SystemDefaultTlsVersions=dword:00000001
在[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727]下面添加:SystemDefaultTlsVersions=dword:00000001
(4)在应用程序中添加以下两个类文件:SslProtocolsExtensions.cs和SecurityProtocolTypeExtensions.cs,内容如下。
//SslProtocolsExtensions.cs using System;
namespace System.Security.Authentication { public static class SslProtocolsExtensions { public const SslProtocols Tls12 = (SslProtocols)0x00000C00; public const SslProtocols Tls11 = (SslProtocols)0x00000300; } }
//SecurityProtocolTypeExtensions.cs using System;
namespace System.Net { using System.Security.Authentication; public static class SecurityProtocolTypeExtensions { public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12; public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11; public const SecurityProtocolType SystemDefault = (SecurityProtocolType)0; } }
(5)在应用程序的主函数main()中添加如下代码,以便HTTP请求中使用TSL1.2安全协议。
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolTypeExtensions.Tls12;
参考链接:
1、TLS 系统默认版本.NET Framework 3.5.1 Windows 7 SP1 和 Server 2008 R2 SP1 中包含的支持
3、TLS 1.2 in .NET Framework 4.0
4、Windows8.1-KB2999226-x64安装提示 此更新不适用你的计算机
5、Http异步发送之HttpWebRequest的BeginGetResponse
两种解决方法下的源码:
1、HTTPRequestAsync-升级到VC#2012+NetFramework4.5:链接:https://pan.baidu.com/s/1iJ5Gdvm4RrUYa_WuGLD2Gw 提取码:6mxr
2、HTTPRequestAsync-VC#2008-安装补丁的代码:链接:https://pan.baidu.com/s/176PLZ0pHCq0KR9MbNk7--A 提取码:60dn