如何获取运行我的C#应用​​程序的服务器的IP地址?

Nef*_*zen 363 c# ip-address

我正在运行服务器,我想显示自己的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;
Run Code Online (Sandbox Code Playgroud)

但是,我一般不信任作者,我不明白这段代码.有没有更好的方法呢?

And*_*are 236

不,这几乎是最好的方法.由于一台机器可能有多个IP地址,您需要迭代它们的集合以找到合适的IP地址.

编辑:我唯一改变的就是改变这个:

if (ip.AddressFamily.ToString() == "InterNetwork")
Run Code Online (Sandbox Code Playgroud)

对此:

if (ip.AddressFamily == AddressFamily.InterNetwork)
Run Code Online (Sandbox Code Playgroud)

没有必要进行ToString枚举以进行比较.

  • 在发现IP之后我还建议使用`break`语句以避免不必要地进一步迭代集合(在这种情况下,我怀疑性能影响是否重要,但我喜欢强调一般良好的编码习惯) (28认同)
  • 请注意,当计算机具有多个"InterNetwork"端口(在我的情况下:以太网卡和虚拟机端口)时,这可能会失败.当前代码将为您提供列表中的最后一个IP. (7认同)
  • "InterNetwork"是机器的IPv4地址. (4认同)
  • 如果可能,我想要外部IP地址.我想如果我支持NAT,那就不可能了. (3认同)
  • 不,您的机器只会知道其NAT地址. (3认同)

ezg*_*gar 164

了解您的公共知识产权的唯一方法是让别人告诉您; 此代码可以帮助您:

public string GetPublicIP()
{
    String direction = "";
    WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
    using (WebResponse response = request.GetResponse())
    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
    {
        direction = stream.ReadToEnd();
    }

    //Search for the ip in the html
    int first = direction.IndexOf("Address: ") + 9;
    int last = direction.LastIndexOf("</body>");
    direction = direction.Substring(first, last - first);

    return direction;
}
Run Code Online (Sandbox Code Playgroud)

  • 您是否知道您的代码示例在问题13中提到了Twenty C#Microsoft Academy的问题解释?演示者为窃取您的代码而道歉.从8:30开始.请参阅[this](http://www.microsoftvirtualacademy.com/Content/ViewContent.aspx?et=8464&m=8456&ct=28536).:) (19认同)
  • 不幸的是链接已经死了 (4认同)
  • 请使用链接http://ipof.in/txt,这样您就可以直接获取IP a,而无需所有HTML解析代码 (3认同)

Moh*_*dil 82

清洁和一体化解决方案:D

//This returns the first IP4 address or null
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
Run Code Online (Sandbox Code Playgroud)

  • 此代码的问题:*它假定计算机只有一个IP地址.许多人有多个.*它只考虑IPV4地址.添加InterNetworkV6以包含IPV6. (3认同)
  • @RobertBratton,感谢您的重播。这个问题并没有假设多IP地址或IPV6,只要稍微修改一下这段代码就可以处理特定的不同问题。 (2认同)

Dr.*_*ice 50

如果您不能依赖从DNS服务器获取您的IP地址(这发生在我身上),您可以使用以下方法:

System.Net.NetworkInformation命名空间包含NetworkInterface类,该类具有静态GetAllNetworkInterfaces方法.

此方法将返回您计算机上的所有"网络接口",即使您的计算机上只安装了无线适配器和/或以太网适配器硬件,也通常会有很多"网络接口".所有这些网络接口都具有本地计算机的有效IP地址,尽管您可能只需要一个.

如果您正在寻找一个IP地址,那么您需要过滤下来的列表,直到您找到正确的地址.您可能需要做一些实验,但我使用以下方法取得了成功:

  • 通过检查筛选出任何处于非活动状态的NetworkInterface OperationalStatus == OperationalStatus.Up.例如,如果您没有插入网络电缆,这将排除您的物理以太网适配器.

对于每个NetworkInterface,您可以使用GetIPProperties方法获取IPInterfaceProperties对象,并且可以从IPInterfaceProperties对象访问UnicastAddresses属性以获取UnicastIPAddressInformation对象的列表.

  • 通过检查过滤掉非首选单播地址 DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
  • 通过检查过滤掉"虚拟"地址AddressPreferredLifetime != UInt32.MaxValue.

此时,我获取与所有这些过滤器匹配的第一个(如果有)单播地址的地址.

编辑:

[修订后的代码于2018年5月16日,包括上述文本中提到的重复地址检测状态和首选寿命]

下面的示例演示了基于操作状态,地址族的过滤,不包括环回地址(127.0.0.1),重复地址检测状态和首选生命周期.

static IEnumerable<IPAddress> GetLocalIpAddresses()
{
    // Get the list of network interfaces for the local computer.
    var adapters = NetworkInterface.GetAllNetworkInterfaces();

    // Return the list of local IPv4 addresses excluding the local
    // host, disconnected, and virtual addresses.
    return (from adapter in adapters
            let properties = adapter.GetIPProperties()
            from address in properties.UnicastAddresses
            where adapter.OperationalStatus == OperationalStatus.Up &&
                  address.Address.AddressFamily == AddressFamily.InterNetwork &&
                  !address.Equals(IPAddress.Loopback) &&
                  address.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred &&
                  address.AddressPreferredLifetime != UInt32.MaxValue
            select address.Address);
}
Run Code Online (Sandbox Code Playgroud)

  • 同意DNS是获取IP地址的更简单方法.我在回答中提到,当DNS不可靠时,这种方法很有效.我在DNS搞砸的环境中使用了这个,这样如果你将一台机器从一个以太网端口移动到另一个端口,DNS仍然会报告旧的IP地址,所以对我来说它几乎没用. (3认同)
  • 在这种特殊情况下,OP希望看到他的外部IP地址,因此DNS解决方案可能就是这样.但是对于迭代本地IP地址,这是我推荐的方法. (2认同)

小智 37

WebClient webClient = new WebClient();
string IP = webClient.DownloadString("http://myip.ozymo.com/");
Run Code Online (Sandbox Code Playgroud)


ope*_*dog 17

using System.Net;

string host = Dns.GetHostName();
IPHostEntry ip = Dns.GetHostEntry(host);
Console.WriteLine(ip.AddressList[0].ToString());
Run Code Online (Sandbox Code Playgroud)

刚刚在我的机器上测试了它,它的工作原理.

  • 它将获得你的本地IP,问题是关于外部IP ieIp与你浏览互联网.. (3认同)

rez*_*eza 15

如果您想避免使用DNS:

List<IPAddress> ipList = new List<IPAddress>();
foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
{
    foreach (var address in netInterface.GetIPProperties().UnicastAddresses)
    {
        if (address.Address.AddressFamily == AddressFamily.InterNetwork)
        {
            Console.WriteLine("found IP " + address.Address.ToString());
            ipList.Add(address.Address);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


bvr*_*376 9

不要一直依赖InterNetwork,因为你可以拥有多个同时使用IP4的设备,这会破坏获取IP的结果.现在,如果您愿意,可以复制一下,请查看或更新为您认为合适的方式.

首先,我得到路由器的地址(网关)如果它返回我连接到网关(这意味着没有直接连接到调制解调器无线),那么我们的网关地址为IPAddress,否则我们是一个空指针IPAddress参考.

然后我们需要获取计算机的IP地址列表.事情并不困难,因为路由器(所有路由器)使用4个字节(...).前三个是最重要的,因为连接到它的任何计算机将具有与前三个字节匹配的IP4地址.例如:192.168.0.1是路由器默认IP的标准,除非由管理员更改.'192.168.0'或者它们可能是我们需要匹配的东西.这就是我在IsAddressOfGateway函数中所做的一切.长度匹配的原因是因为并非所有地址(仅用于计算机)都具有4个字节的长度.如果在cmd中键入netstat,您会发现这是真的.所以你有它.是的,真正得到你想要的东西需要更多的工作.排除法.并且为了上帝的缘故,不要通过ping它来找到地址,这需要花费时间,因为首先你要发送要被ping的地址,然后它必须发回结果.不,直接使用.Net类来处理您的系统环境,当您必须单独使用计算机时,您将获得所需的答案.

现在如果你直接连接到你的调制解调器,过程几乎是相同的,因为调制解调器是你的网关,但子掩码不一样,因为你通过调制解调器直接从你的DNS服务器获取信息,而不是由提供调制解调器的路由器屏蔽互联网给你,虽然你仍然可以使用相同的代码,因为分配给调制解调器的IP的最后一个字节是1.所以如果从调制解调器发送的IP确实改变是111.111.111.1'那么你将获得111.111.111.(一些字节值).请记住,我们需要找到网关信息,因为有更多设备处理互联网连接而不是路由器和调制解调器.

现在你明白为什么你不要改变你的路由器的前两个字节192和168.这些只是严格区分路由器而不是互联网使用,否则我们会遇到严重的IP协议和双重ping问题导致计算机崩溃.您分配的路由器IP为192.168.44.103的图像,并且您也单击具有该IP的站点.我的天啊!您的计算机不知道要ping什么.崩溃就在那里.为避免此问题,仅为路由器分配这些,而不是用于Internet使用.所以留下路由器的前两个字节.

static IPAddress FindLanAddress()
{
    IPAddress gateway = FindGetGatewayAddress();
    if (gateway == null)
        return null;

    IPAddress[] pIPAddress = Dns.GetHostAddresses(Dns.GetHostName());

    foreach (IPAddress address in pIPAddress)            {
        if (IsAddressOfGateway(address, gateway))
                return address;
    return null;
}
static bool IsAddressOfGateway(IPAddress address, IPAddress gateway)
{
    if (address != null && gateway != null)
        return IsAddressOfGateway(address.GetAddressBytes(),gateway.GetAddressBytes());
    return false;
}
static bool IsAddressOfGateway(byte[] address, byte[] gateway)
{
    if (address != null && gateway != null)
    {
        int gwLen = gateway.Length;
        if (gwLen > 0)
        {
            if (address.Length == gateway.Length)
            {
                --gwLen;
                int counter = 0;
                for (int i = 0; i < gwLen; i++)
                {
                    if (address[i] == gateway[i])
                        ++counter;
                }
                return (counter == gwLen);
            }
        }
    }
    return false;

}
static IPAddress FindGetGatewayAddress()
{
    IPGlobalProperties ipGlobProps = IPGlobalProperties.GetIPGlobalProperties();

    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        IPInterfaceProperties ipInfProps = ni.GetIPProperties();
        foreach (GatewayIPAddressInformation gi in ipInfProps.GatewayAddresses)
            return gi.Address;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 无法保证"连接到网关的任何计算机都具有与前三个字节匹配的IP4地址".它取决于子网掩码,它可以包含各种位组合.此外,起始字节不必是"192.168",如[此处所述](http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces).此代码仅在子网掩码为"255.255.255.0"时才有效,并且它将以相当复杂的方式IMO执行此操作. (3认同)

bæl*_*zor 8

我只是想我会添加自己的,单行(即使已经有许多其他有用的答案).


string ipAddress = new WebClient().DownloadString("http://icanhazip.com");

  • 请注意,这可能会导致内存泄漏.WebClient未正确处理.相反,使用:using(var client = new WebClient()){return client.DownloadString("http://icanhazip.com/").Trim(); } (4认同)