如何使用 HttpClient 从特定 IP 地址发送请求? C#

Posted

技术标签:

【中文标题】如何使用 HttpClient 从特定 IP 地址发送请求? C#【英文标题】:How to use HttpClient to send a Request from a specific IP address? C# 【发布时间】:2016-09-25 17:41:58 【问题描述】:

我在服务器上有多个 IP,并且想选择在使用 HttpClient 类从 API 获取/发布数据时要使用的其中一个。 (或者甚至同时发送请求,但使用 2 个 IP 而不仅仅是一个)

我已经看到一些使用委托的 HttpWebRequest (here) 的示例,但我想继续使用 HttpClient 实现。

【问题讨论】:

【参考方案1】:

[这将是一个 hacky 代码,因为没有方法/属性可以访问 ServicePoint ]

您可以使用反射来访问底层的ServicePoint,如下所示 (由于没有公共/私有字段/属性可以访问此值,我将挂钩 startRequest 委托)

HttpClientHandler SetServicePointOptions(HttpClientHandler handler)

    var field = handler.GetType().GetField("_startRequest", BindingFlags.NonPublic| BindingFlags.Instance); // Fieldname has a _ due to being private
    var startRequest = (Action<object>)field.GetValue(handler);

    Action<object> newStartRequest = obj =>
    
        var webReqField = obj.GetType().GetField("webRequest", BindingFlags.NonPublic | BindingFlags.Instance);
        var webRequest = webReqField.GetValue(obj) as HttpWebRequest;
        webRequest.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);

        startRequest(obj); //call original action
    ;

    field.SetValue(handler, newStartRequest); //replace original 'startRequest' with the one above

    return handler;

BindIPEndPointCallback 是您linked 在您的问题中的那个人。根据需要修改它。 现在你可以像这样使用这个方法了

HttpClientHandler handler = SetServicePointOptions(new HttpClientHandler());
HttpClient client = new HttpClient(handler);
var str = await client.GetStringAsync("https://google.com");

【讨论】:

只是为了对此进行更新,对于任何使用此代码的人,不要像我一样被抓住。首先,事实上 .net 核心团队已经实现了 HttpClientHandler 等,而无需在其中放置与服务点相关的任何内容,因此您将编写所有代码以发现它默默无闻,更不用说此示例中的此代码了有效会中断。还谈到这段代码的主要警告 --- 第一个字段名称不正确,它应该是 _startRequest 否则你会得到 null ref 错误并使用完整的框架而不是核心。 非常感谢您的评论。我遇到了完全相同的问题,设置 servicePoint.bindIpEndPointDelegate 确实适用于 .net fx 但不适用于 .net 核心!最后我不得不将我的代码切换到 .net fx

以上是关于如何使用 HttpClient 从特定 IP 地址发送请求? C#的主要内容,如果未能解决你的问题,请参考以下文章

如何获取静态IP地址?

HttpClient SendAsync 阻塞主线程

如何将访问特定URL的IP地址存储到文件中

能使用httpclient伪造客户访问IP吗

对一个 IP 范围的多个 HttpClient 异步请求

有没有办法用 C ping 特定的 IP 地址?