You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中不使用Dns.GetHostEntry()获取IPHostEntry值的替代方案

替代Dns.GetHostEntry()的可行方案

根据你的代码需求,核心是获取目标主机的IP地址列表,以下是两种可行的替代方案:

方案一:使用Dns.GetHostAddresses()构造IPHostEntry

Dns.GetHostAddresses()方法直接返回目标主机的IP地址数组,你可以用它手动构造IPHostEntry对象,完全满足原有代码的需求:

String urlSvr = m.Groups[2].Value.ToLower();
IPAddress[] addresses = Dns.GetHostAddresses(machine);
IPHostEntry serverEntry = new IPHostEntry
{
    AddressList = addresses,
    HostName = machine // 若需要真实主机名,可结合其他逻辑获取,或直接使用传入的machine值
};

if (urlSvr == machine || machine.StartsWith(urlSvr) || urlSvr == serverEntry.AddressList[0].ToString())
{
    _log.Debug(String.Format(CultureInfo.InvariantCulture, "Machine match {0}, {1}", machine, urlSvr));
}

这个方案最简洁,和原方法核心逻辑对齐,完全覆盖现有代码的使用场景。

方案二:P/Invoke调用底层GetAddrInfo函数(Windows平台)

如果需要更底层的DNS解析控制,可以直接调用Windows系统的GetAddrInfoAPI,手动解析并构造IPHostEntry:

using System;
using System.Net;
using System.Runtime.InteropServices;
using System.Globalization;

// 定义P/Invoke相关结构体和函数
[StructLayout(LayoutKind.Sequential)]
internal struct addrinfo
{
    public int ai_flags;
    public int ai_family;
    public int ai_socktype;
    public int ai_protocol;
    public IntPtr ai_addrlen;
    public IntPtr ai_canonname;
    public IntPtr ai_addr;
    public IntPtr ai_next;
}

[StructLayout(LayoutKind.Sequential)]
internal struct sockaddr_in
{
    public short sin_family;
    public ushort sin_port;
    public uint sin_addr;
    public byte[] sin_zero;
}

[DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int GetAddrInfo(string pNodeName, string pServiceName, IntPtr pHints, out IntPtr ppResult);

[DllImport("ws2_32.dll")]
internal static extern void FreeAddrInfo(IntPtr pAddrInfo);

// 自定义解析方法
private static IPHostEntry GetHostEntryAlternative(string machine)
{
    IntPtr result = IntPtr.Zero;
    try
    {
        int error = GetAddrInfo(machine, null, IntPtr.Zero, out result);
        if (error != 0)
            throw new System.ComponentModel.Win32Exception(error);

        var addresses = new System.Collections.Generic.List<IPAddress>();
        string hostName = machine;

        IntPtr ptr = result;
        while (ptr != IntPtr.Zero)
        {
            addrinfo info = Marshal.PtrToStructure<addrinfo>(ptr);
            if (info.ai_canonname != IntPtr.Zero)
                hostName = Marshal.PtrToStringUni(info.ai_canonname);

            if (info.ai_addr != IntPtr.Zero && info.ai_family == 2) // 解析IPv4
            {
                sockaddr_in sockAddr = Marshal.PtrToStructure<sockaddr_in>(info.ai_addr);
                byte[] ipBytes = BitConverter.GetBytes(sockAddr.sin_addr);
                Array.Reverse(ipBytes);
                addresses.Add(new IPAddress(ipBytes));
            }
            else if (info.ai_addr != IntPtr.Zero && info.ai_family == 23) // 如需支持IPv6,可补充此处逻辑
            {
                // IPv6解析代码
            }

            ptr = info.ai_next;
        }

        return new IPHostEntry
        {
            AddressList = addresses.ToArray(),
            HostName = hostName
        };
    }
    finally
    {
        if (result != IntPtr.Zero)
            FreeAddrInfo(result);
    }
}

// 使用示例
String urlSvr = m.Groups[2].Value.ToLower();
IPHostEntry serverEntry = GetHostEntryAlternative(machine);

if (urlSvr == machine || machine.StartsWith(urlSvr) || urlSvr == serverEntry.AddressList[0].ToString())
{
    _log.Debug(String.Format(CultureInfo.InvariantCulture, "Machine match {0}, {1}", machine, urlSvr));
}

这个方案适合需要自定义DNS解析逻辑的场景,但仅适用于Windows平台,代码复杂度较高。

内容的提问来源于stack exchange,提问作者zia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:18:09