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

How to bind HttpClient to a specific (source) ip address in .NET 5

根据 issue #1793 it shouldn't be necessary to use quirks 将 .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 地址来使用。请不要将我送到第 3 方图书馆。是的,即使他们在这方面修复了 WebClient,我也不想使用它。

其他感兴趣的问题:

.NET Core,因此 .NET 5 也支持各种 HttpHandlerSocketsHttpHandler 用于配置 HttpClient 以使用 .NET 内部套接字实现(不依赖于 WinHttp)。

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

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