C# 如何从HttpClient获取有关连接的信息(IP地址)

C# 如何从HttpClient获取有关连接的信息(IP地址),c#,C#,我的服务向其他服务进行外部调用。它有助于了解已建立连接的确切IP地址(以防需要跟进这些服务的所有者) 我正在使用HttpClient。有没有一种方法可以获取底层IP地址(反射很好)?灵感来源于和帖子 可以通过反射访问底层ServicePoint并覆盖BindIPEndPoint: private static void TryHttpClientWithServicePoint() { var webRequestHandler = SetServicePointOptions(new

我的服务向其他服务进行外部调用。它有助于了解已建立连接的确切IP地址(以防需要跟进这些服务的所有者)

我正在使用HttpClient。有没有一种方法可以获取底层IP地址(反射很好)?

灵感来源于和帖子

可以通过反射访问底层ServicePoint并覆盖BindIPEndPoint:

private static void TryHttpClientWithServicePoint()
{
    var webRequestHandler = SetServicePointOptions(new WebRequestHandler());
    var client = new HttpClient(webRequestHandler);
    var content = client.GetStringAsync("https://stackoverflow.com").Result;
    Console.WriteLine(content.Substring(0, 256));
}

private static WebRequestHandler SetServicePointOptions(WebRequestHandler handler)
{
    var field = typeof(HttpClientHandler).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 = BindIPEndPoint;

        startRequest(obj); //call original action
    };

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

    return handler;
}

public static IPEndPoint BindIPEndPoint(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
    Console.WriteLine($"IP address = {remoteEndPoint}");
    return null;
}
private static void TryHttpClientWithServicePoint()
{
var webRequestHandler=SetServicePointOptions(新的webRequestHandler());
var client=新的HttpClient(webRequestHandler);
var content=client.GetStringAsync(“https://stackoverflow.com三、结果;
Console.WriteLine(content.Substring(0256));
}
私有静态WebRequestHandler SetServicePointOptions(WebRequestHandler处理程序)
{
var field=typeof(HttpClientHandler).GetField(“\u startRequest”,
BindingFlags.NonPublic | BindingFlags.Instance);//由于是私有的,Fieldname有一个
var startRequest=(操作)field.GetValue(处理程序);
操作newStartRequest=obj=>
{
var webReqField=obj.GetType().GetField(“webRequest”,BindingFlags.NonPublic | BindingFlags.Instance);
var webRequest=webReqField.GetValue(obj)作为HttpWebRequest;
webRequest.ServicePoint.BindIPEndPointDelegate=BindIPEndPoint;
startRequest(obj);//调用原始操作
};
field.SetValue(handler,newStartRequest);//将原来的“startRequest”替换为上面的一个
返回处理程序;
}
公共静态IPEndPoint BindIPEndPoint(ServicePoint ServicePoint、IPEndPoint remoteEndPoint、int retryCount)
{
WriteLine($“IP地址={remoteEndPoint}”);
返回null;
}
允许访问远程IP:

灵感来自和帖子

可以通过反射访问底层ServicePoint并覆盖BindIPEndPoint:

private static void TryHttpClientWithServicePoint()
{
    var webRequestHandler = SetServicePointOptions(new WebRequestHandler());
    var client = new HttpClient(webRequestHandler);
    var content = client.GetStringAsync("https://stackoverflow.com").Result;
    Console.WriteLine(content.Substring(0, 256));
}

private static WebRequestHandler SetServicePointOptions(WebRequestHandler handler)
{
    var field = typeof(HttpClientHandler).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 = BindIPEndPoint;

        startRequest(obj); //call original action
    };

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

    return handler;
}

public static IPEndPoint BindIPEndPoint(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
    Console.WriteLine($"IP address = {remoteEndPoint}");
    return null;
}
private static void TryHttpClientWithServicePoint()
{
var webRequestHandler=SetServicePointOptions(新的webRequestHandler());
var client=新的HttpClient(webRequestHandler);
var content=client.GetStringAsync(“https://stackoverflow.com三、结果;
Console.WriteLine(content.Substring(0256));
}
私有静态WebRequestHandler SetServicePointOptions(WebRequestHandler处理程序)
{
var field=typeof(HttpClientHandler).GetField(“\u startRequest”,
BindingFlags.NonPublic | BindingFlags.Instance);//由于是私有的,Fieldname有一个
var startRequest=(操作)field.GetValue(处理程序);
操作newStartRequest=obj=>
{
var webReqField=obj.GetType().GetField(“webRequest”,BindingFlags.NonPublic | BindingFlags.Instance);
var webRequest=webReqField.GetValue(obj)作为HttpWebRequest;
webRequest.ServicePoint.BindIPEndPointDelegate=BindIPEndPoint;
startRequest(obj);//调用原始操作
};
field.SetValue(handler,newStartRequest);//将原来的“startRequest”替换为上面的一个
返回处理程序;
}
公共静态IPEndPoint BindIPEndPoint(ServicePoint ServicePoint、IPEndPoint remoteEndPoint、int retryCount)
{
WriteLine($“IP地址={remoteEndPoint}”);
返回null;
}
允许访问远程IP:


但是您已经连接到远程地址,为什么不能使用它呢?HttpClient包含一个连接池,它不建立单个连接,而是根据需要创建连接。如果存在负载平衡器,那么到同一服务的多个连接可能会以不同的IP地址结束,这取决于服务的提供方式。例如:感兴趣的?:您是否确实与“这些服务的所有者”进行了检查,以确定提供IP是否对他们有用?可以为HttpWebRequest执行此操作:。我想知道是否有办法获取HttpClient的类似信息。但是您已经连接到远程地址,为什么不能使用它?HttpClient包含一个连接池,它不建立单个连接,而是根据需要创建连接。如果存在负载平衡器,那么到同一服务的多个连接可能会以不同的IP地址结束,这取决于服务的提供方式。例如:感兴趣的?:您是否确实与“这些服务的所有者”进行了检查,以确定提供IP是否对他们有用?可以为HttpWebRequest执行此操作:。我想知道是否有一种方法可以为HttpClient获取类似的信息。