C# .Net核心HttpClient错误?SocketException:远程主机强制关闭了现有连接
以下代码在完整的.Net framework控制台程序中运行时没有任何错误。但是,它在.NETCore2.1中运行时出现以下错误 System.AggregateException HResult=0x80131500 Message=One or more errors occurred. Source=System.Private.CoreLib StackTrace: at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at ConsoleApp1.Program.requestString(String url) in C:\source\repos\ConsoleApp1\Program.cs:line 38 at ConsoleApp1.Program.Main(String[] args) in C:\source\repos\ConsoleApp1\Program.cs:line 13 Inner Exception 1: HttpRequestException: The SSL connection could not be established, see inner exception. Inner Exception 2: IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. Inner Exception 3: SocketException: An existing connection was forcibly closed by the remote host System.AggregateException HResult=0x80131500 消息=发生了一个或多个错误。 Source=System.Private.CoreLib 堆栈跟踪: 位于System.Threading.Tasks.Task`1.GetResultCore(布尔waitCompletionNotification) 在C:\source\repos\ConsoleApp1\Program.cs中的ConsoleApp1.Program.requestString(字符串url)处:第38行 在C:\source\repos\ConsoleApp1\Program.cs中的ConsoleApp1.Program.Main(字符串[]args)处:第13行 内部异常1: HttpRequestException:无法建立SSL连接,请参阅内部异常。 内部例外2: IOException:无法从传输连接读取数据:远程主机强制关闭了现有连接。 内部例外3: SocketException:远程主机强制关闭了现有连接 代码:C# .Net核心HttpClient错误?SocketException:远程主机强制关闭了现有连接,c#,.net-core,C#,.net Core,以下代码在完整的.Net framework控制台程序中运行时没有任何错误。但是,它在.NETCore2.1中运行时出现以下错误 System.AggregateException HResult=0x80131500 Message=One or more errors occurred. Source=System.Private.CoreLib StackTrace: at System.Threading.Tasks.Task`1.GetResultCore(Boo
class Program
{
static void Main(string[] args)
{
var url = "https://google.com";
var (statusCode, html) = requestString(url);
Console.WriteLine("%d %s", statusCode, html);
}
static CookieContainer cc = new CookieContainer();
static HttpClientHandler handler = new HttpClientHandler { AllowAutoRedirect = false, CookieContainer = cc };
public static async Task<(int statusCode, string content)> requestStringAsync(string url)
{
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
// | SecurityProtocolType.Ssl3;
using (var request = new HttpRequestMessage { RequestUri = new Uri(url), Method = HttpMethod.Get })
using (var client = new HttpClient(handler))
{
var response = await client.SendAsync(request); // Error (actual line)
// response.EnsureSuccessStatusCode() |> ignore
var statusCode = (int)response.StatusCode;
var content = await response.Content.ReadAsStringAsync();
return (statusCode, content);
}
}
public static (int statusCode, string content) requestString(string url)
{
return requestStringAsync(url).Result;
}
}
类程序
{
静态void Main(字符串[]参数)
{
变量url=”https://google.com";
var(statusCode,html)=请求字符串(url);
Console.WriteLine(“%d%s”,状态码,html);
}
静态CookieContainer cc=新CookieContainer();
静态HttpClientHandler处理程序=新HttpClientHandler{AllowAutoRedirect=false,CookieContainer=cc};
公共静态异步任务requestStringAsync(字符串url)
{
ServicePointManager.ServerCertificateValidationCallback+=(发件人、证书、链、sslPolicyErrors)=>true;
ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
//| SecurityProtocolType.Ssl3;
使用(var-request=new-HttpRequestMessage{RequestUri=new-Uri(url),Method=HttpMethod.Get})
使用(var客户端=新的HttpClient(处理程序))
{
var response=wait client.sendaync(请求);//错误(实际行)
//response.EnsureSuccessStatusCode()|>忽略
var statusCode=(int)response.statusCode;
var content=await response.content.ReadAsStringAsync();
返回(状态码、内容);
}
}
公共静态(int statusCode,string content)请求字符串(string url)
{
返回requestStringAsync(url).Result;
}
}
有一个关于.NET Core 2.1的预览版提到了这个问题。这可能就是原因。但是,我也注意到您的TLS设置不正确。您当前正在启用它,但会覆盖已设置的所有其他协议。与此相反:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
您应该使用以下选项:
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
// ----------------------------------^
我认为这是一个次要问题,但仍然值得解决
更新
上面提到的GitHub问题有一个讨论,最终链接到官方的发布。它的意思如下:
Sockets性能和SocketsHttpHandler
我们对.NETCore2.1中的套接字进行了重大改进。套接字是传出和传入网络通信的基础。.NETCore2.1中的高级网络API,包括HttpClient和Kestrel,现在基于.NETSockets。在早期版本中,这些高级API基于本机网络实现
您可以使用以下机制之一将进程配置为使用较旧的HttpClientHandler:
从代码中,使用AppContext类:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
AppContext开关也可以通过配置文件设置
同样可以通过环境变量DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER实现。要选择退出,请将该值设置为false或0
在我的例子中,根本原因是使用了HttpClient.GetAsync(url)的多个并发调用。我通过将HttpClient实例设置为singleton来修复它 更多信息 因此,HttpClient只需实例化一次,并在应用程序的整个生命周期中重用。为每个请求实例化HttpClient类将耗尽重载下可用的套接字数量。该问题将导致SocketException错误。解决这个问题的可能方法是将HttpClient对象创建为单例对象或静态对象
您是否尝试过
dotnet dev certs https--trust
?我已更新了SecurityProtocal分配,但它仍然出现异常。@ca9163d9我已为您更新了答案。我认为值得一读链接的GitHub问题以及MSDN公告。