在互联网上有几个地方告诉你如何获得一个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地址感兴趣:例如,如果某人希望访问我计算机中的共享文件夹,我将给他的IP地址。

如果我没有连接到网络,我直接通过没有路由器的调制解调器连接到互联网,那么我希望得到一个错误。我如何才能看到我的计算机是否连接到网络与c#,如果它是然后得到局域网IP地址。


当前回答

为了搞笑,我想我应该尝试使用新的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)。

其他回答

Imports System.Net
Imports System.Net.Sockets
Function LocalIP()
    Dim strHostName = Dns.GetHostName
    Dim Host = Dns.GetHostEntry(strHostName)
    For Each ip In Host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            txtIP.Text = ip.ToString
        End If
    Next

    Return True
End Function

下面是同样的动作

Function LocalIP()

   Dim Host As String =Dns.GetHostEntry(Dns.GetHostName).AddressList(1).MapToIPv4.ToString

   txtIP.Text = Host

   Return True

End Function

我还在努力获取正确的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);

下面是一个修改后的版本(来自compman2408的版本),它对我来说很有效:

    internal static string GetLocalIPv4(NetworkInterfaceType _type)
    {  // Checks your IP adress from the local network connected to a gateway. This to avoid issues with double network cards
        string output = "";  // default output
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces()) // Iterate over each network interface
        {  // Find the network interface which has been provided in the arguments, break the loop if found
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {   // Fetch the properties of this adapter
                IPInterfaceProperties adapterProperties = item.GetIPProperties();
                // Check if the gateway adress exist, if not its most likley a virtual network or smth
                if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
                {   // Iterate over each available unicast adresses
                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {   // If the IP is a local IPv4 adress
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {   // we got a match!
                            output = ip.Address.ToString();
                            break;  // break the loop!!
                        }
                    }
                }
            }
            // Check if we got a result if so break this method
            if (output != "") { break; }
        }
        // Return results
        return output;
    }

你可以像这样调用这个方法:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

变化:我正在从一个适配器中检索IP,该适配器已分配了一个网关IP。 第二个变化:我添加了文档字符串和break语句,以使该方法更有效。

已经有很多答案了,但我还是贡献我的一个:

public static IPAddress LocalIpAddress() {
    Func<IPAddress, bool> localIpPredicate = ip =>
        ip.AddressFamily == AddressFamily.InterNetwork &&
        ip.ToString().StartsWith("192.168"); //check only for 16-bit block
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(localIpPredicate);
}

一个衬套:

public static IPAddress LocalIpAddress() => Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.ToString().StartsWith("192.168"));

注意:从last开始搜索,因为它在一些接口添加到设备后仍然有效,如MobileHotspot,VPN或其他花哨的虚拟适配器。

我知道这可能是白费力气,但也许这能帮到别人。我到处寻找一种方法来找到我的本地IP地址,但我发现到处都说要使用:

Dns.GetHostEntry(Dns.GetHostName());

I don't like this at all because it just gets all the addresses assigned to your computer. If you have multiple network interfaces (which pretty much all computers do now-a-days) you have no idea which address goes with which network interface. After doing a bunch of research I created a function to use the NetworkInterface class and yank the information out of it. This way I can tell what type of interface it is (Ethernet, wireless, loopback, tunnel, etc.), whether it is active or not, and SOOO much more.

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地址,但您的计算机没有安装无线卡,它将只返回一个空字符串。以太网接口也是如此。

编辑:

It was pointed out (thanks @NasBanov) that even though this function goes about extracting the IP address in a much better way than using Dns.GetHostEntry(Dns.GetHostName()) it doesn't do very well at supporting multiple interfaces of the same type or multiple IP addresses on a single interface. It will only return a single IP address when there may be multiple addresses assigned. To return ALL of these assigned addresses you could simply manipulate the original function to always return an array instead of a single string. For example:

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();