c# - .Net 核心 HttpClient 错误?套接字异常 : An existing connection was forcibly closed by the remote host

标签 c# .net-core

以下代码在完整的 .Net 框架控制台程序中运行时没有任何错误。但是在.Net core 2.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

Code:

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;
    }
}

最佳答案

有一个bug对于 .NET Core 2.1 Preview 提到了这个问题。这可能是原因。但是,我也注意到您的 TLS 设置不正确。您当前正在启用它,但会覆盖已设置的所有其他协议(protocol)。而不是这个:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

你应该使用这个:

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
// ----------------------------------^

我认为这是一个次要问题,但仍然值得解决。

更新

上面引用的 GitHub 问题有一个讨论,最终链接到 .NET Core 2.1 SDK Preview 2 的官方公告。 .它有以下内容:

Sockets Performance and SocketsHttpHandler

We made major improvements to sockets in .NET Core 2.1. Sockets are the basis of both outgoing and incoming networking communication. The higher-level networking APIs in .NET Core 2.1, including HttpClient and Kestrel, are now based on .NET sockets. In earlier versions, these higher-level APIs were based on native networking implementations.

...

You can use one of the following mechanisms to configure a process to use the older HttpClientHandler:

From code, use the AppContext class:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

The AppContext switch can also be set by config file.

The same can be achieved via the environment variable DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER. To opt out, set the value to either false or 0.

关于c# - .Net 核心 HttpClient 错误?套接字异常 : An existing connection was forcibly closed by the remote host,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51732289/

相关文章:

docker - 在 Raspberry Pi 3B+ 上运行 ASP .NET Core

c# - SerialPort.BytesToWrite 的用法

C# - 如何从 json 动态对象中检索数组?

c# - 如何读取 Azure Function 应用程序内的配置 json 文件

c# - 带有 Moq 的 Stubed 工作单元方法不返回预期的整数

c# - 为什么我们在升级到 Core 2.1 和 Framework 4.7.2 后在 ServiceStack 中收到 TypeIntializer Exception?

.net-core - 使用 IdentityServer 承载的 SignalR 不会从集线器接收任何 JWTBearerEvents

c# - 是否可以为 .NET 中的类定义别名?

c# - Web 服务的日期格式问题

c# - WP7 - 从 CSV 文件读取?或者如何处理数据?