Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .Net核心HttpClient错误?SocketException:远程主机强制关闭了现有连接_C#_.net Core - Fatal编程技术网

C# .Net核心HttpClient错误?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

以下代码在完整的.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:远程主机强制关闭了现有连接 代码:

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公告。