如何将 HttpClient 绑定到 .NET 5 中的特定(源)IP 地址

Mat*_*ias 6 c# dotnet-httpclient .net-5

根据问题 #1793,不需要使用像这样的怪癖将 .NET 5 中的 HttpClient 绑定到特定的本地 IP 地址。

然而,我对这个主题完全不知所措,同时 .NET Core 开发人员多年来一直无法为 .NET Core 提供选择 http 请求的传出 IP 地址的选项。即使向后兼容的 WebClient 也无法在早期的 .NET Core 版本中执行此操作,任何其他高级 HTTP API 也无法执行此操作。上帝(或任何人)赞扬 .NET 5,它应该(希望如此?)将此类功能带回现代 .NET 框架。

如何配置HttpClient对象以仅使用 .NET 5 中的 on-bord 方法为传出连接选择特定的本地 IP 地址?还是仍然不可能?附加问题:如何配置ClientWebSocket对象以仅使用 .NET 5 中的 on-bord 方法为传出连接选择特定的本地 IP 地址?

在我的设置中,计算机有多个 IP 地址,并且我正在访问的服务根据源 IP 地址有相当严格的速率限制。

请不要告诉我,操作系统会选择要使用的正确适配器或 IP 地址。请不要将我发送到第三方图书馆。是的,即使他们WebClient在这方面解决了我也不想使用它。

其他感兴趣的问题:

  • #23267 : HttpClient 指定要绑定到/发出请求的接口
  • #28721:在 SocketsHttpHandler (又名自定义拨号器)上添加 ConnectCallback

Mat*_*ias 12

.NET Core 以及 .NET 5 支持各种HttpHandler功能。用于SocketsHttpHandler配置HttpClient使用 .NET 内部套接字实现(不依赖 WinHttp)。

从 .NET 5 开始,您可以使用 的ConnectCallbackSocketsHttpHandler配置如何建立连接,如下所示:

public static HttpClient GetHttpClient(IPAddress address)
{
    if (IPAddress.Any.Equals(address))
        return new HttpClient();

    SocketsHttpHandler handler = new SocketsHttpHandler();

    handler.ConnectCallback = async (context, cancellationToken) =>
    {
        Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

        socket.Bind(new IPEndPoint(address, 0));

        socket.NoDelay = true;

        try
        {
            await socket.ConnectAsync(context.DnsEndPoint, cancellationToken).ConfigureAwait(false);

            return new NetworkStream(socket, true);
        }
        catch
        {
            socket.Dispose();

            throw;
        }
    };

    return new HttpClient(handler);
}
Run Code Online (Sandbox Code Playgroud)