首页 文章

获取本地IP地址

提问于
浏览
217

在互联网上有几个地方向您展示如何获得IP地址 . 其中很多看起来像这个例子:

String strHostName = string.Empty;
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;

for (int i = 0; i < addr.Length; i++)
{
    Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
}
Console.ReadLine();

在这个例子中,我得到了几个IP地址,但我只对路由器分配给运行程序的计算机的那个感兴趣:如果他希望访问我计算机中的共享文件夹,我会给某人的IP实例 .

如果我没有连接到网络,我通过没有路由器的调制解调器直接连接到互联网,那么我想得到一个错误 . 如何查看我的计算机是否使用C#连接到网络,以及是否要获取LAN IP地址 .

21 回答

  • 20

    获取本地IP地址:

    public static string GetLocalIPAddress()
    {
        var host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (var ip in host.AddressList)
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                return ip.ToString();
            }
        }
        throw new Exception("No network adapters with an IPv4 address in the system!");
    }
    

    要检查您是否已连接:

    System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

  • 4

    当本地计算机上有多个IP地址时,有一种更准确的方法 . Connect 一个UDP套接字并读取其本地 endpoints :

    string localIP;
    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
    {
        socket.Connect("8.8.8.8", 65530);
        IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
        localIP = endPoint.Address.ToString();
    }
    

    UDP套接字上的 Connect 具有以下效果:它设置 Send / Recv 的目标,丢弃来自其他地址的所有数据包,以及 - 我们使用的 - 将套接字转移到"connected"状态,设置其相应的字段 . 这包括根据系统的路由表检查到目的地的路由是否存在,并相应地设置本地 endpoints . 最后一部分似乎没有正式的文档,但它看起来像Berkeley sockets API(UDP "connected"状态的副作用)的整体特征,在版本和发行版的Windows _739674中都可靠地工作 .

    因此,此方法将提供用于连接到指定远程主机的本地地址 . 没有 Build 真正的连接,因此指定的远程IP可以无法访问 .

  • 0

    重构Mrcheif的代码以利用Linq(即.Net 3.0) . .

    private IPAddress LocalIPAddress()
    {
        if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            return null;
        }
    
        IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    
        return host
            .AddressList
            .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
    }
    

    :)

  • -3

    我知道这可能会踢死马,但也许这可以帮助别人 . 我到处寻找一种方法来查找我的本地IP地址,但我觉得它在哪里都可以使用:

    Dns.GetHostEntry(Dns.GetHostName());
    

    我根本不喜欢这个,因为它只是获取分配给您计算机的所有地址 . 如果您有多个网络接口(几乎所有计算机现在都可以这样做),您不知道哪个地址与哪个网络接口有关 . 在做了大量的研究之后,我创建了一个使用NetworkInterface类的函数,并从中获取信息 . 通过这种方式,我可以分辨出它是什么类型的接口(以太网,无线,环回,隧道等),它是否处于活动状态,以及更多的SOOO .

    public string GetLocalIPv4(NetworkInterfaceType _type)
    {
        string output = "";
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {
                foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
                {
                    if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        output = ip.Address.ToString();
                    }
                }
            }
        }
        return output;
    }
    

    现在获取以太网网络接口的IPv4地址调用:

    GetLocalIPv4(NetworkInterfaceType.Ethernet);
    

    或者您的无线接口:

    GetLocalIPv4(NetworkInterfaceType.Wireless80211);
    

    如果您尝试获取无线接口的IPv4地址,但您的计算机没有安装无线卡,则只会返回一个空字符串 . 以太网接口也是如此 .

    希望这有助于某人! :-)

    EDIT:

    有人指出(感谢@NasBanov)即使这个函数以比使用_739681更好的方式提取IP地址,但它在支持单个相同类型的多个接口或多个IP地址方面做得不是很好接口 . 当可能分配多个地址时,它将仅返回单个IP地址 . 要返回所有这些分配的地址,您可以简单地操作原始函数以始终返回数组而不是单个字符串 . 例如:

    public static string[] GetAllLocalIPv4(NetworkInterfaceType _type)
    {
        List<string> ipAddrList = new List<string>();
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {
                foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
                {
                    if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        ipAddrList.Add(ip.Address.ToString());
                    }
                }
            }
        }
        return ipAddrList.ToArray();
    }
    

    现在,此函数将返回特定接口类型的所有已分配地址 . 现在只获取一个字符串,您可以使用 .FirstOrDefault() 扩展名返回数组中的第一个项目,如果它为空,则返回一个空字符串 .

    GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
    
  • 14

    这是一个修改后的版本(来自compman2408的版本),它对我有用:

    internal static string GetLocalIPv4(NetworkInterfaceType _type)
    {
        string output = "";
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties adapterProperties = item.GetIPProperties();
    
                if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
                {
                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            output = ip.Address.ToString();
                        }
                    }
                }
            }
        }
    
        return output;
    }
    

    更改:我正在从分配了网关IP的适配器中检索IP .

  • 0

    这是我发现获取当前IP的最佳代码,避免获取VMWare主机或其他无效IP地址 .

    public string GetLocalIpAddress()
    {
        UnicastIPAddressInformation mostSuitableIp = null;
    
        var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    
        foreach (var network in networkInterfaces)
        {
            if (network.OperationalStatus != OperationalStatus.Up)
                continue;
    
            var properties = network.GetIPProperties();
    
            if (properties.GatewayAddresses.Count == 0)
                continue;
    
            foreach (var address in properties.UnicastAddresses)
            {
                if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                    continue;
    
                if (IPAddress.IsLoopback(address.Address))
                    continue;
    
                if (!address.IsDnsEligible)
                {
                    if (mostSuitableIp == null)
                        mostSuitableIp = address;
                    continue;
                }
    
                // The best IP is the IP got from DHCP server
                if (address.PrefixOrigin != PrefixOrigin.Dhcp)
                {
                    if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
                        mostSuitableIp = address;
                    continue;
                }
    
                return address.Address.ToString();
            }
        }
    
        return mostSuitableIp != null 
            ? mostSuitableIp.Address.ToString()
            : "";
    }
    
  • 4

    我认为使用LinQ更容易:

    Dns.GetHostEntry(Dns.GetHostName())
       .AddressList
       .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
       .ToString()
    
  • 99

    @mrcheif我今天找到了这个答案,它虽然确实返回了错误的IP(不是由于代码不能正常工作),但是当你有Himachi运行这样的东西时它给出了错误的互联网络IP,它非常有用 .

    public static string localIPAddress()
    {
        IPHostEntry host;
        string localIP = "";
        host = Dns.GetHostEntry(Dns.GetHostName());
    
        foreach (IPAddress ip in host.AddressList)
        {
            localIP = ip.ToString();
    
            string[] temp = localIP.Split('.');
    
            if (ip.AddressFamily == AddressFamily.InterNetwork && temp[0] == "192")
            {
                break;
            }
            else
            {
                localIP = null;
            }
        }
    
        return localIP;
    }
    
  • 152

    为了笑,我想我会尝试通过使用新的C#6空条件运算符获得单个LINQ语句 . 看起来很疯狂,可能非常低效,但它确实有效 .

    private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
    {
        // Bastardized from: http://stackoverflow.com/a/28621250/2685650.
    
        return NetworkInterface
            .GetAllNetworkInterfaces()
            .FirstOrDefault(ni =>
                ni.NetworkInterfaceType == type
                && ni.OperationalStatus == OperationalStatus.Up
                && ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null
                && ni.GetIPProperties().UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) != null
            )
            ?.GetIPProperties()
            .UnicastAddresses
            .FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)
            ?.Address
            ?.ToString()
            ?? string.Empty;
    }
    

    逻辑由 Gerardo H 提供(并参考 compman2408 ) .

  • -8

    先决条件:您必须添加System.Data.Linq引用并引用它

    using System.Linq;
    string ipAddress ="";
    IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
    ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));
    
  • 7

    使用linq表达式获取IP的其他方法:

    public static List<string> GetAllLocalIPv4(NetworkInterfaceType type)
    {
        return NetworkInterface.GetAllNetworkInterfaces()
                       .Where(x => x.NetworkInterfaceType == type && x.OperationalStatus == OperationalStatus.Up)
                       .SelectMany(x => x.GetIPProperties().UnicastAddresses)
                       .Where(x => x.Address.AddressFamily == AddressFamily.InterNetwork)
                       .Select(x => x.Address.ToString())
                       .ToList();
    }
    
  • 1
    string str="";
    
    System.Net.Dns.GetHostName();
    
    IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(str);
    
    IPAddress[] addr = ipEntry.AddressList;
    
    string IP="Your Ip Address Is :->"+ addr[addr.Length - 1].ToString();
    
  • 1

    请记住,在一般情况下,您可以进行多个NAT转换,以及多个dns服务器,每个服务器在不同的NAT转换级别上运行 .

    如果您有运营商级NAT,并希望与其他人通信,该怎么办?同一承运人的客户?在一般情况下,您永远不会确定,因为在每次NAT转换时,您可能会显示不同的主机名 .

  • 2

    已经过时了,这对我有用

    public static IPAddress GetIPAddress()
    { 
     IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
     address.AddressFamily == AddressFamily.InterNetwork).First();
     return ip;
    }
    
  • 364

    更新Mrchief与Linq的答案,我们将:

    public static IPAddress GetLocalIPAddress()
    {
       var host = Dns.GetHostEntry(Dns.GetHostName());
       var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
       return ipAddress;
    }
    
  • 1

    我也在努力获得正确的IP .

    我在这里尝试了各种解决方案但没有一个能给我带来理想的效果 . 几乎所有提供的条件测试都没有导致使用地址 .

    这对我有用,希望它有帮助......

    var firstAddress = (from address in NetworkInterface.GetAllNetworkInterfaces().Select(x => x.GetIPProperties()).SelectMany(x => x.UnicastAddresses).Select(x => x.Address)
                        where !IPAddress.IsLoopback(address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
                        select address).FirstOrDefault();
    
    Console.WriteLine(firstAddress);
    
  • 1

    只是使用LINQ的我的更新版本:

    /// <summary>
    /// Gets the local Ipv4.
    /// </summary>
    /// <returns>The local Ipv4.</returns>
    /// <param name="networkInterfaceType">Network interface type.</param>
    IPAddress GetLocalIPv4(NetworkInterfaceType networkInterfaceType)
    {
        var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType == networkInterfaceType && i.OperationalStatus == OperationalStatus.Up);
    
        foreach (var networkInterface in networkInterfaces)
        {
            var adapterProperties = networkInterface.GetIPProperties();
    
            if (adapterProperties.GatewayAddresses.FirstOrDefault() == null)
                    continue;
            foreach (var ip in networkInterface.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                        continue;
    
                return ip.Address;
            }
        }
    
        return null;
    }
    
  • 2
    Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]
    

    一行代码:D

  • 86

    使用一个或多个LAN卡和虚拟机进行了测试

    public static string DisplayIPAddresses()
        {
            string returnAddress = String.Empty;
    
            // Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)
            NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    
            foreach (NetworkInterface network in networkInterfaces)
            {
                // Read the IP configuration for each network
                IPInterfaceProperties properties = network.GetIPProperties();
    
                if (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
                       network.OperationalStatus == OperationalStatus.Up &&
                       !network.Description.ToLower().Contains("virtual") &&
                       !network.Description.ToLower().Contains("pseudo"))
                {
                    // Each network interface may have multiple IP addresses
                    foreach (IPAddressInformation address in properties.UnicastAddresses)
                    {
                        // We're only interested in IPv4 addresses for now
                        if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                            continue;
    
                        // Ignore loopback addresses (e.g., 127.0.0.1)
                        if (IPAddress.IsLoopback(address.Address))
                            continue;
    
                        returnAddress = address.Address.ToString();
                        Console.WriteLine(address.Address.ToString() + " (" + network.Name + " - " + network.Description + ")");
                    }
                }
            }
    
           return returnAddress;
        }
    
  • 1

    如果您有虚拟机或额外的网卡,则地址列表中可能还有其他值 . 我的建议是检查地址列表和打印的条目是否合适 . 在我的情况下,条目3是我的机器的ipv4地址

    IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
    IPAddress ipAddr = ipHost.AddressList[3];
    string ip = ipAddr.ToString();
    

    别忘了添加 using System.Net;

  • 1

    这里有一个功能齐全的实心1-liner,用于本地IP地址问题 . 使用并行执行语言Dyalog APL制作 . 有趣的是,这段次代码支持0,1或多个IPv4适配器 - 结果只是一个长度为0,1或n的封闭文本向量的数组 .

    主要是因为你的困惑,我猜:-)

    #.Dns.(a.AddressFamily.(⎕THIS=InterNetwork)/a←(GetHostEntry GetHostName).AddressList).ToString
    

    返回(对于这台计算机):192.168.0.100(< - 单元素盒装向量,第一个元素是13个字符的文本向量)

相关问题