在互联网上有几个地方向您展示如何获得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地址.
获取本地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();
当本地计算机上有多个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(); }
Connect
在UDP套接字上具有以下效果:它设置Send
/ 的目的地Recv
,丢弃来自其他地址的所有数据包,以及 - 我们使用的 - 将套接字转换为"已连接"状态,设置其相应的字段.这包括根据系统的路由表检查到目的地的路由是否存在,并相应地设置本地端点.最后一部分似乎没有正式的文档,但它看起来像是Berkeley套接字API(UDP"连接"状态的副作用)的一个完整特征,它可以在Windows 和Linux中跨版本和发行版可靠地工作.
因此,此方法将提供用于连接到指定远程主机的本地地址.没有建立真正的连接,因此指定的远程IP可以无法访问.
重构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地址,但我发现它在任何地方都说使用:
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地址,但您的计算机没有安装无线卡,则只会返回一个空字符串.以太网接口也是如此.
希望这有助于某人!:-)
编辑:
有人指出(感谢@NasBanov)即使这个函数以比使用Dns.GetHostEntry(Dns.GetHostName())
它更好的方式提取IP地址,但在单个接口上支持相同类型的多个接口或多个IP地址也不是很好.当可能分配多个地址时,它将仅返回单个IP地址.要返回所有这些分配的地址,您可以简单地操作原始函数以始终返回数组而不是单个字符串.例如:
public static string[] GetAllLocalIPv4(NetworkInterfaceType _type) { ListipAddrList = new List (); 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();
这是一个修改后的版本(来自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(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) .ToString()
笑了一下,以为我会尝试使用新的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
)。
@mrcheif I found this answer today and it was very useful although it did return a wrong IP (not due to the code not working) but it gave the wrong internetwork IP when you have such things as Himachi running.
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; }
使用linq表达式获取IP的其他方法:
public static ListGetAllLocalIPv4(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(); }