如何使用 HttpClient 从特定 IP 地址发送请求? C#
How to use HttpClient to send a Request from a specific IP address? C#
我在服务器上有多个 IP,在使用 HttpClient class 到 get/post 来自 API 的数据时,我想选择要使用的 IP。
(或者甚至同时发送请求但使用 2 个 IP 而不仅仅是一个)
我看过一些使用委托的 HttpWebRequest (here) 的示例,但我想继续使用 HttpClient 实现。
[ 这将是一个 hacky 代码,因为没有 method/property 访问 ServicePoint ]
您可以使用反射来访问底层的 ServicePoint,如下所示
(由于没有 public/private field/property 来访问这个值,我将 hook 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");
我在服务器上有多个 IP,在使用 HttpClient class 到 get/post 来自 API 的数据时,我想选择要使用的 IP。 (或者甚至同时发送请求但使用 2 个 IP 而不仅仅是一个)
我看过一些使用委托的 HttpWebRequest (here) 的示例,但我想继续使用 HttpClient 实现。
[ 这将是一个 hacky 代码,因为没有 method/property 访问 ServicePoint ]
您可以使用反射来访问底层的 ServicePoint,如下所示 (由于没有 public/private field/property 来访问这个值,我将 hook 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");