我正在运行一个服务器,我想显示我自己的IP地址。

获取计算机自身(如果可能的话,外部)IP地址的语法是什么?

有人编写了以下代码。

IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
    if (ip.AddressFamily.ToString() == "InterNetwork")
    {
        localIP = ip.ToString();
    }
}
return localIP;

然而,我通常不信任作者,我不理解这段代码。有更好的方法吗?


当前回答

使用LINQ获取所有IP地址为字符串:

using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
...
string[] allIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork)
        .Select(d=>d.Address.ToString())
    ).ToArray();

为了过滤掉私人信息…

首先,定义一个扩展方法IsPrivate():

public static class IPAddressExtensions
{
    // Collection of private CIDRs (IpAddress/Mask) 
    private static Tuple<int, int>[] _privateCidrs = new []{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}
        .Select(c=>Tuple.Create(BitConverter.ToInt32(IPAddress
                                    .Parse(c.Split('/')[0]).GetAddressBytes(), 0)
                              , IPAddress.HostToNetworkOrder(-1 << (32-int.Parse(c.Split('/')[1])))))
        .ToArray();
    public static bool IsPrivate(this IPAddress ipAddress)
    {
        int ip = BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0);
        return _privateCidrs.Any(cidr=>(ip & cidr.Item2)==(cidr.Item1 & cidr.Item2));           
    }
}

... 然后用它来过滤私人ip:

string[] publicIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork
            && !d.Address.IsPrivate() // Filter out private ones
        )
        .Select(d=>d.Address.ToString())
    ).ToArray();

其他回答

也许通过外部IP,您可以考虑(如果您在Web服务器上下文中)使用此方法

Request.ServerVariables["LOCAL_ADDR"];

我也在问你同样的问题,我在这篇stackoverflow的文章中找到了它。

这对我很管用。

return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);

简单的一行代码,返回第一个内部IPV4地址,如果没有则返回null。作为上面的注释添加,但可能对某人有用(上面的一些解决方案将返回多个需要进一步过滤的地址)。

它也很容易返回环回而不是null,我猜用:

return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) ?? new IPAddress( new byte[] {127, 0, 0, 1} );
private static string GetLocalIpAdresse()
    {
        var host = Dns.GetHostEntry(Dns.GetHostName());
        foreach(var ip in host.AddressList)
        {
            if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                return ip.ToString();
            }
        }
        throw new Exception  ("No network adapters with an IPv4 address in the system");
    }
namespace NKUtilities 
{
    using System;
    using System.Net;
    using System.Net.Sockets;

    public class DNSUtility
    {
        public static int Main(string [] args)
        {
            string strHostName = "";
            try {

                if(args.Length == 0)
                {
                    // 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);
                }
                else
                {
                    // Otherwise, get the IP address of the host provided on the command line.
                    strHostName = args[0];
                }

                // 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());
                }
                return 0;

            } 
            catch(SocketException se) 
            {
                Console.WriteLine("{0} ({1})", se.Message, strHostName);
                return -1;
            } 
            catch(Exception ex) 
            {
                Console.WriteLine("Error: {0}.", ex.Message);
                return -1;
            }
        }
    }
}

详情请看这里。

你必须记住你的电脑可以有多个IP(实际上它总是这样)-所以你是哪一个。

这是我解决它的方法。我知道如果你有几个物理接口,这可能不会选择你想要的确切的eth。

private string FetchIP()
{
    //Get all IP registered
    List<string> IPList = new List<string>();
    IPHostEntry host;
    host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            IPList.Add(ip.ToString());
        }
    }

    //Find the first IP which is not only local
    foreach (string a in IPList)
    {
        Ping p = new Ping();
        string[] b = a.Split('.');
        string ip2 = b[0] + "." + b[1] + "." + b[2] + ".1";
        PingReply t = p.Send(ip2);
        p.Dispose();
        if (t.Status == IPStatus.Success && ip2 != a)
        {
            return a;
        }
    }
    return null;
}