防止 Dns.GetHostAddresses 抛出异常?

Posted

技术标签:

【中文标题】防止 Dns.GetHostAddresses 抛出异常?【英文标题】:Prevent Dns.GetHostAddresses from throwing exceptions? 【发布时间】:2018-12-23 06:59:12 【问题描述】:

因此,使用已死网站的主机名调用 Dns.GetHostAddresses 通常会引发异常,指出“不知道这样的主机”。

我的用例中的异常会导致大量额外的 CPU 使用,而这些额外的 CPU 使用可能是致命的。

有没有办法重写该方法以仅返回 null 或其他内容?

异常是一个 SocketException,表明它使用了套接字,我查看了 Reference Source 并没有在 DNS.GetHostAddresses(string) 中找到任何套接字引用。我确实看到创建了一个 SocketException 对象,但它没有被使用。

【问题讨论】:

随时欢迎您编写您自己的行为方式,但您可以随心所欲。 @itsme86 我只需要一种将主机名转换为 IP 以通过 TCPClient 连接的方法,因为它在使用 IP 时往往会更有效。我怎么会“写我自己的”。 与 .NET 开发人员的做法相同。您甚至可以从链接到的源代码开始,然后对其进行调整。 @itsme86 这就是我所尝试的,但它使用了很多 .net 内部,我无法访问,或者即使我创建到我的应用程序命名空间的新文件中,也会有很多权限错误。 你解决了多少个域,捕获异常的开销是“致命的”? 【参考方案1】:

我不确定我是否正确理解了您的问题,但您是否正在尝试实现这样的目标?

private void button1_Click(object sender, EventArgs e)
    
        try
        
            IPHostEntry hostEntry;

            hostEntry = Dns.GetHostEntry(textBox3.Text);

            if (hostEntry.AddressList.Length > 0)
            
                var ip = hostEntry.AddressList[0];
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                s.Connect(ip, 80);
                textBox5.Text = ip.ToString();
            

        
        catch
        
             textBox5.Text = "No Conversion available";
        

【讨论】:

OP 说异常太贵了。 GetHostEntry 是否已弃用?【参考方案2】:

使用 P/Invoke 访问 Win32 DNS API。从这里开始:https://www.pinvoke.net/default.aspx/dnsapi.DnsQuery

【讨论】:

【参考方案3】:

尝试使用Dns.BeginGetHostAddresses() IAsyncResult 回调。 如果 Host 条目不可解析(这是大多数 System.Net 方法的工作方式,无论喜欢与否),但在 UI 线程中未引发,则无法避免异常。

我不确定这是否能解决问题,但在运行它时我没有注意到任何 CPU 峰值(只是第一次使用它,但该方法是从 Button 点击事件中调用的)。

IPAddress ResolvedIpAddress = null;
GetHostIpAddressAsync("www.hfkhkhfhkf.com", this.ResolvedAddressCallback);


protected internal void ResolvedAddressCallback(IPAddress address)

    this.ResolvedIpAddress = address;
    //Eventually, if an UI update is needed
    this.BeginInvoke((MethodInvoker)delegate  
        label1.Text = address != null 
                    ? ResolvedIpAddress.ToString() 
                    : "<Host not found>";
    );


internal static void GetHostIpAddressAsync(string sHostName, Action<IPAddress> BGHAActionCallback)

    IPAddress IpAddress = null;
    Dns.BeginGetHostAddresses(sHostName, new AsyncCallback((asyncResult) =>
    
        try
        
            IPAddress[] ipAddresses = Dns.EndGetHostAddresses(asyncResult);
            if (BGHAActionCallback != null)
            
                if (ipAddresses.Length > 0)
                    IpAddress = ipAddresses[0];
                BGHAActionCallback?.Invoke(IpAddress);
            
        
        catch (Exception)  BGHAActionCallback?.Invoke(null); 
    ), null);

【讨论】:

以上是关于防止 Dns.GetHostAddresses 抛出异常?的主要内容,如果未能解决你的问题,请参考以下文章

unity 获取本机ip地址

如何确定本地主机的 IPv4 地址?

获取本机IPV4地址

网络编程方法提取以及简介

C#获取客户端Ip工具类

C# 如何获取本机IP