获取本地IP地址

在互联网上有几个地方,告诉你如何得到一个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地址,如果他想访问我的计算机中的共享文件夹实例。

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

获取本地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();

重构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); } 

🙂

当本地机器上有多个IP地址时,有一个更准确的方法。 Connect一个UDP套接字并读取其本地端点:

 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的目的地,丢弃所有来自其他地址的数据包,以及 – 我们使用的是 – 将套接字转换为“连接”状态,设置适当的字段。 这包括根据系统路由表检查是否存在到目的地的路由,并相应地设置本地端点。 最后一部分似乎没有正式记载,但它看起来像Berkeley套接字API (UDP“连接”状态的一个副作用)的一个整体特征,可以在Windows 和Linux之间在各种版本和发行版中可靠地工作。

所以,这个方法会给出用来连接指定远程主机的本地地址。 没有build立真正的连接,因此指定的远程IP不可达。

我知道这可能是踢死马,但也许这可以帮助一个人。 我看遍了各地的方式来find我的本地IP地址,但我发现它说使用的地方:

 Dns.GetHostEntry(Dns.GetHostName()); 

我不喜欢这一点,因为它只是获得分配给你的计算机的所有地址。 如果你有多个networking接口(现在几乎所有的计算机都是现在这样做的话),你不知道哪个networking接口使用哪个地址。 在做了一堆研究之后,我创build了一个使用NetworkInterface类的函数,并将其中的信息抽出。 这样我就可以知道它是什么types的接口(以太网,无线,环回,隧道等),是否活动,以及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; } 

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

 GetLocalIPv4(NetworkInterfaceType.Ethernet); 

或者你的无线接口:

 GetLocalIPv4(NetworkInterfaceType.Wireless80211); 

如果您尝试获取无线接口的IPv4地址,但是您的计算机没有安装无线网卡,则只会返回一个空string。 与以太网接口一样的东西。

希望这可以帮助别人! 🙂

编辑:

有人指出(谢谢@NasBanov),即使这个函数用了比使用Dns.GetHostEntry(Dns.GetHostName())更好的方法来提取IP地址,但它并不能很好地支持相同types或多个IP地址在单个接口上。 当可能分配了多个地址时,它只会返回一个IP地址。 要返回所有这些分配的地址,您可以简单地操作原始函数,始终返回一个数组而不是一个string。 例如:

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

现在这个函数将返回所有指定地址的特定接口types。 现在只需要一个string,就可以使用.FirstOrDefault()扩展来返回数组中的第一个项目,或者如果它是空的,则返回一个空string。

 GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault(); 

这是一个修改后的版本(来自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。

这是我发现获得当前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() : ""; } 

我认为使用LinQ更容易:

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

@mrcheif我今天发现了这个答案,它是非常有用的,虽然它确实返回了一个错误的IP(不是由于代码不工作),但它给了错误的互联网IP,当你有像Himachi运行的东西。

 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; } 

对于一个笑,我想我会试图通过使用新的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 )。

先决条件:您必须添加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)); 
 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(); 

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

如果你有运营商级的NAT,并且想和同一家运营商的其他客户进行交stream呢? 在一般情况下,你永远不知道,因为你可能在每次NAT转换时出现不同的主机名。

只是我使用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 (NetworkInterface networkInterface in networkInterfaces) { var adapterProperties = networkInterface.GetIPProperties(); if (adapterProperties.GatewayAddresses.FirstOrDefault() != null) { foreach (UnicastIPAddressInformation ip in networkInterface.GetIPProperties().UnicastAddresses) { if (ip.Address.AddressFamily == AddressFamily.InterNetwork) { return ip.Address; } } } } return null; } 

用linqexpression式获取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(); } 
 Dns.GetHostEntry(Dns.GetHostName()).AddressList[1] 

一行代码:D

如果您有虚拟机或额外的网卡,地址列表中可能会有其他值。 我的build议是检查地址列表的条目和打印哪个是适当的。 在我的情况下,条目3是我的机器的ipv4地址

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

不要忘记添加using System.Net;

这里为本地IP地址提供了一个function完善的固定单线问题。 用并行执行语言Dyalog APL制成。 有趣的是,这个小代码支持0,1或多个IPv4适配器 – 结果将只是一个长度为0,1或n的封闭文本向量的数组。

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

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

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