現象描述:
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