【问题标题】:How do I find the local IP address on a Win 10 UWP project如何在 Win 10 UWP 项目中找到本地 IP 地址
【发布时间】:2016-02-19 14:53:16
【问题描述】:

我目前正在尝试将管理控制台应用程序移植到 Win 10 UWP 应用程序。我在使用以下控制台代码中的 System.Net.Dns 时遇到问题。

如何获取设备IP

这是我尝试移植的控制台应用程序代码。

public static string GetIP4Address()
{
    string IP4Address = String.Empty;
    foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
    {
        if (IPA.AddressFamily == AddressFamily.InterNetwork)
        {
            IP4Address = IPA.ToString();
            break;
        }
    }
    return IP4Address;
}

【问题讨论】:

    标签: c# ip uwp


    【解决方案1】:

    使用它来获取 UWP 应用中的主机 IP 地址,我已经测试过了:

        foreach (HostName localHostName in NetworkInformation.GetHostNames())
        {
            if (localHostName.IPInformation != null)
            {
                if (localHostName.Type == HostNameType.Ipv4)
                {
                    textblock.Text = localHostName.ToString();
                    break;
                }
            }
        }
    

    并查看 API 文档here

    【讨论】:

    • 如果您说 VirtualBox,这将不起作用,在我的情况下,表达式 NetworkInformation.GetHostNames().FirstOrDefault(name => name.Type == HostNameType.Ipv4)?.DisplayName ?? “???”;正在返回由 VirtualBox 设置的虚拟交换机的 IP 地址
    • 为了解释为什么会这样,the docsIPInformation 属性仅在 HostName 对象是 GetHostNames 方法返回的本地 IPv4 或 IPv6 地址时设置。此属性表示本地 IP 地址的 IPInformation 对象。如果 HostName 对象不是本地 IPv4 或 IPv6 地址,则此属性将为空。
    • 请问,由于我有多个 DCHP 地址(用于 Wi-Fi 和以太网),如何确保始终获得 Wi-Fi 地址?由于循环在第一个实例上中断,这是因为 Wi-Fi 地址总是第一个吗?
    【解决方案2】:

    你可以这样试试:

    private string GetLocalIp()
    {
        var icp = NetworkInformation.GetInternetConnectionProfile();
    
        if (icp?.NetworkAdapter == null) return null;
        var hostname =
            NetworkInformation.GetHostNames()
                .SingleOrDefault(
                    hn =>
                        hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
                        == icp.NetworkAdapter.NetworkAdapterId);
    
        // the ip address
        return hostname?.CanonicalName;
    }
    

    上面的答案也是对的

    【讨论】:

    • 我很难决定使用其中的哪一个,所以经过一些实验后,我将返回答案复选标记。
    • 看来它们都可以工作,但我标记了第二个,因为它是在一个返回字符串的方法中,就像我原来的例子一样。它也有点像编码偏好的“我的风格”。谢谢大家,你们拯救了这一天。
    • 此代码确实返回本地 IP 地址,“其他代码”返回您的设备或本地网络用于上网的 IP 地址。
    • 这会引发 LINQ 异常 - 在我的情况下,序列包含多个匹配元素(正如我在其他评论中所写,我的适配器列表中也有一个由 VirtualBox 设置的虚拟交换机)。我将其更改为 FirstOrDefault 而不是 SingleOrDefault 以绕过它,它返回了 IPv6 地址。请参阅我的答案以获得 Ipv4 的修复
    • @panda 的其他答案也可能返回错误答案(在我的情况下是 VirtualBox 设置的虚拟交换机的地址)
    【解决方案3】:

    基于@John Zhang 的回答,但已修复不引发多个匹配项的 LINQ 错误并返回 Ipv4 地址:

       public static string GetFirstLocalIp(HostNameType hostNameType = HostNameType.Ipv4)
        {
            var icp = NetworkInformation.GetInternetConnectionProfile();
    
            if (icp?.NetworkAdapter == null) return null;
            var hostname =
                NetworkInformation.GetHostNames()
                    .FirstOrDefault(
                        hn =>
                            hn.Type == hostNameType &&
                            hn.IPInformation?.NetworkAdapter != null && 
                            hn.IPInformation.NetworkAdapter.NetworkAdapterId == icp.NetworkAdapter.NetworkAdapterId);
    
            // the ip address
            return hostname?.CanonicalName;
        }
    

    显然,您可以传递 HostNameType.Ipv6 而不是 Ipv4,这是获取 Ipv6 地址的默认(隐式)参数值

    【讨论】:

    • 请注意,在我在 LINQ 查询中添加 HostNameType 检查后,它停止抛出有关多个匹配项的异常,但为了安全起见,我将 SingleOrDefault 更改为 FirstOrDefault
    • 想知道为什么有人对这个答案投了反对票,而这个答案是纠正其他答案的答案(返回错误的 IP 地址)
    • 这是最好的答案。不知道为什么这被否决了,因为您的答案是大多数情况下使用的最佳代码。此外,FirstOrDefault 也是在这里使用的最佳 LINQ 方法,因为一台机器上可以有多个 IP 地址 IPV4 或 IPV6。调用 GetFirstLocalIP() 函数,一切正常。
    • 确实,改名了
    猜你喜欢
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    相关资源
    最近更新 更多