获取计算机自身(如果可能的话,外部)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;
但是,我通常不信任作者,并且我不理解该代码。有更好的方法吗?
#1 楼
不,那几乎是最好的方法。由于一台机器可能有多个IP地址,因此您需要迭代它们的集合以找到合适的IP地址。编辑:我唯一要更改的就是更改此内容:
if (ip.AddressFamily.ToString() == "InterNetwork")
对此:
if (ip.AddressFamily == AddressFamily.InterNetwork)
无需
ToString
枚举进行比较。评论
如果可能,我需要外部IP地址。我想如果我落后于NAT,那将不可能。
– Nefzen
09年7月1日在13:38
不,您的计算机将仅知道其NAT地址。
–安德鲁·黑尔(Andrew Hare)
09年7月1日在13:39
我非常确定您将需要连接到外部服务器来获取外部地址。
– Thiago Arrais
09年7月1日在14:23
我还建议在找到IP后使用break语句,以避免不必要的遍历整个集合(在这种情况下,我怀疑性能影响是否会很重要,但我想强调总体上良好的编码习惯)
– Eric J.
2011年4月26日15:53
请注意,当计算机具有多个“ InterNetwork”端口(在我的情况下:一个以太网卡和一个虚拟机端口)时,这可能会失败。当前代码将为您提供列表中的最后一个IP。
–克里斯蒂安·斯杜德(Christian Studer)
2011年4月28日在9:12
#2 楼
知道您的公共IP的唯一方法是让别人告诉您;该代码可能会帮助您: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;
}
评论
您是否知道Microsoft学院的问题13二十个C#问题中提到您的代码示例?主持人为窃取您的代码表示歉意。从8:30分钟开始。看到这个。 :)
–欧文(Erwin Rooijakkers)
2014年8月24日在20:42
不幸的是链接已死。
–巴兹·古文卡亚(Baz Guvenkaya)
2015年5月21日,2:11
新链接,以防有人想看
– Kimmax
16年7月5日在2:07
请使用链接ipof.in/txt,这样您就可以直接获得IP,而无需所有HTML解析代码
– vivekv
16-09-28在18:30
#3 楼
清洁剂和多合一解决方案:D//This returns the first IP4 address or null
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
评论
此代码存在问题:*假定计算机只有一个IP地址。许多有多个。 *它仅考虑IPV4地址。添加InterNetworkV6以包括IPV6。
–罗伯特·布拉顿
2014年10月31日15:19
@RobertBratton,谢谢您的重播。该问题并未假定使用多个IP地址或IPV6,只需对此代码稍加修改即可处理特定的不同问题。
– Mohammed A. Fadil
2014年11月1日7:09
#4 楼
如果您不能依靠从DNS服务器获取IP地址(这已经发生在我身上),则可以使用以下方法:System.Net.NetworkInformation命名空间包含一个NetworkInterface类,该方法具有静态的GetAllNetworkInterfaces方法。
此方法将返回计算机上的所有“网络接口”,即使您只有无线适配器和/或以太网适配器,通常也有很多“网络接口”计算机上安装的硬件。所有这些网络接口都具有适用于本地计算机的有效IP地址,尽管您可能只想要一个。
如果要查找一个IP地址,则需要向下过滤列表,直到您可以确定正确的地址。您可能需要做一些试验,但是我使用以下方法成功了:
通过检查
OperationalStatus == OperationalStatus.Up
过滤掉所有不活动的NetworkInterface。例如,如果没有插入网络电缆,这将排除物理以太网适配器。对于每个NetworkInterface,可以使用GetIPProperties方法从IPInterfaceProperties获取IPInterfaceProperties对象。对象,您可以访问UnicastAddresses属性以获取UnicastIPAddressInformation对象列表。
通过检查
DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
过滤出“虚拟”来过滤出非首选的单播地址。通过检查
AddressPreferredLifetime != UInt32.MaxValue
来查找地址。此时,我采用与所有这些过滤器匹配的第一个(如果有)单播地址。
编辑:
[2018年5月16日经过修改的代码,其中包括上面文本中提到的重复地址检测状态和首选生存期的条件]
下面的示例演示了基于操作状态,地址的过滤系列,不包括环回地址(127.0.0.1),重复地址检测状态和Preferredre d寿命。
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);
}
评论
在这种特殊情况下,OP希望查看其外部IP地址,因此DNS解决方案可能是解决之道。但是对于迭代本地IP地址,这是我推荐的方法。
–马特·戴维斯(Matt Davis)
2012年10月31日上午8:01
同意DNS是获取IP地址的更简单方法。我在回答中提到,当您的DNS不可靠时,此方法有效。我在DNS混乱的环境中使用了此环境,因此,如果将一台计算机从一个以太网端口移至另一个以太网端口,DNS仍会报告旧的IP地址,因此对于我的目的而言几乎没有用。
–维利博士的学徒
13年4月13日在17:21
我感谢所有描述,但是您也应该发布了代码示例。
–爱丁
15年2月2日在18:49
非常感谢。请注意,在最近的Windows更新之后,UnicastAddresses。第一个假设不再成立。我现在需要检查每个适配器的所有UnicastAddress,并使用AddressPreferredLifetime和DuplicateAddressDetectionStation进行进一步过滤(在上面的文本中提到)
–user3085342
18 Mar 15 '18 2:58
#5 楼
WebClient webClient = new WebClient();
string IP = webClient.DownloadString("http://myip.ozymo.com/");
评论
ifconfig.me/ip不再起作用。尝试使用api.ipify.org或Doug注释中的链接
–肯尼83
16 Dec 29'在10:46
#6 楼
using System.Net;
string host = Dns.GetHostName();
IPHostEntry ip = Dns.GetHostEntry(host);
Console.WriteLine(ip.AddressList[0].ToString());
只需在我的机器上对其进行测试就可以了。
评论
它会为您提供本地IP,问题是关于外部IP的IP,即您用来浏览Internet的IP。
– Sangram Nandkhile
2011年4月7日在19:58
#7 楼
如果要避免使用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);
}
}
}
#8 楼
不要一直依赖于InterNetwork,因为您可以拥有不止一台同时使用IP4的设备,这将使获取IP的结果更加复杂。现在,如果您想复制此文件,请查看或将其更新为您认为合适的方式。
首先我获得路由器(网关)的地址
如果返回时我已连接到网关(这意味着未直接连接)进入无线调制解调器),然后将网关地址设为IPAddress,否则将使用空指针IPAddress引用。
然后我们需要获取计算机的IPAddress列表。这不是一件难事,因为路由器(所有路由器)使用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;
}
评论
这没有道理:foreach(ipInfProps.GatewayAddresses中的GatewayIPAddressInformation gi)返回gi.Address;
–埃德温·埃文斯(Edwin Evans)
2012年7月3日,0:06
无法保证“连接到网关的任何计算机都将具有与前三个字节匹配的IP4地址”。它取决于子网掩码,子网掩码可以包含各种位组合。而且,起始字节不必为“ 192.168”,如此处所述。仅当子网掩码为255.255.255.0时,此代码才有效,并且它将以IMO相当复杂的方式进行。
– Groo
13年1月15日在22:04
#9 楼
我只是以为我会添加自己的单行代码(即使已经有许多其他有用的答案)。string ipAddress = new WebClient().DownloadString("http://icanhazip.com");
评论
请注意,这可能会导致内存泄漏。 WebClient未正确处理。而是使用:using(var client = new WebClient()){return client.DownloadString(“ icanhazip.com /”)。Trim(); }
– FOO
2014年9月18日下午4:18
#10 楼
要获取当前的公共IP地址,您需要做的就是创建一个ASPX页面,并在页面加载事件上添加以下行:Response.Write(HttpContext.Current.Request.UserHostAddress.ToString());
#11 楼
如果您在Intranet中运行,则可以使用以下方法获取本地计算机的IP地址,否则,您将获得外部ip地址:Web:
//this will bring the IP for the current machine on browser
System.Web.HttpContext.Current.Request.UserHostAddress
桌面:
//This one will bring all local IPs for the desired namespace
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
#12 楼
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(实际上总是如此)-因此,您追求的是哪个。
#13 楼
试试这个: IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
String MyIp = localIPs[0].ToString();
评论
这将返回许多本地IP地址,其中一个是IPv4地址,但是很难在列表中找到正确的IP地址。
– Contango
2011-09-15 14:34
#14 楼
也许通过外部IP,您可以考虑使用(如果您在Web服务器环境中)Request.ServerVariables["LOCAL_ADDR"];
我问的是与您相同的问题,我在此找到了它stackoverflow文章。
对我有用。
#15 楼
namespace NKUtilities
{
using System;
using System.Net;
public class DNSUtility
{
public static int Main (string [] args)
{
String strHostName = new String ("");
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
{
strHostName = args[0];
}
// Then using host name, get the IP address list..
IPHostEntry ipEntry = DNS.GetHostByName (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;
}
}
}
#16 楼
using System;
using System.Net;
namespace IPADDRESS
{
class Program
{
static void Main(string[] args)
{
String strHostName = string.Empty;
if (args.Length == 0)
{
/* First get the host name of local machine.*/
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
}
else
{
strHostName = args[0];
}
/* Then using host name, get the IP address list..*/
IPHostEntry ipEntry = Dns.GetHostByName(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();
}
}
}
#17 楼
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} );
评论
IPAddress.Loopback怎么样? :)
– CodeTherapist
2012年10月12日17:20
#18 楼
要查找IP地址列表,我已使用此解决方案public static IEnumerable<string> GetAddresses()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
return (from ip in host.AddressList where ip.AddressFamily == AddressFamily.lo select ip.ToString()).ToList();
}
但是我个人喜欢下面的解决方案来获取本地有效的IP地址
public static IPAddress GetIPAddress(string hostName)
{
Ping ping = new Ping();
var replay = ping.Send(hostName);
if (replay.Status == IPStatus.Success)
{
return replay.Address;
}
return null;
}
public static void Main()
{
Console.WriteLine("Local IP Address: " + GetIPAddress(Dns.GetHostName()));
Console.WriteLine("Google IP:" + GetIPAddress("google.com");
Console.ReadLine();
}
#19 楼
LINQ解决方案:Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).FirstOrDefault() ?? ""
#20 楼
这是我解决的方法。我知道您是否有几个物理接口,这可能无法选择您想要的确切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;
}
#21 楼
问题不是说ASP.NET MVC,而是我还是把它留在这里:Request.UserHostAddress
评论
这仅在涉及请求时才有效。如果它是每两个小时在服务器上运行一次的工作程序,该怎么办?
–法国
10月5日13:52
#22 楼
使用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();
过滤出私有ONES ...
首先,定义扩展方法
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();
#23 楼
它对我有用...在大多数情况下(如果不是全部的话)应该比查询DNS服务器要快。感谢Wily博士的学徒(在这里)。// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
List<NetworkInterface> candidates = new List<NetworkInterface>();
if (NetworkInterface.GetIsNetworkAvailable())
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (
NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
candidates.Add(ni);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
// Accoring to our tech, the main NetworkInterface should have a Gateway
// and it should be the ony one with a gateway.
if (candidates.Count > 1)
{
for (int n = candidates.Count - 1; n >= 0; n--)
{
if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
{
candidates.RemoveAt(n);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
}
// Fallback to try by getting my ipAdress from the dns
IPAddress myMainIpAdress = null;
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
{
myMainIpAdress = ip;
break;
}
}
if (myMainIpAdress != null)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.Address.Equals(myMainIpAdress))
{
return ni;
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4, AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.GetPhysicalAddress().Equals(mac))
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
{
if (ai.Address.AddressFamily == addressFamily)
{
return ai.Address;
}
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
NetworkInterface ni = GetMainNetworkInterface();
IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
if (ipAddress == null) // could it be possible ?
{
ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
}
return ipAddress;
}
// ******************************************************************
作为参考,这是我定义的完整类代码:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace TcpMonitor
{
/*
Usage:
var cons = TcpHelper.GetAllTCPConnections();
foreach (TcpHelper.MIB_TCPROW_OWNER_PID c in cons) ...
*/
public class NetHelper
{
[DllImport("iphlpapi.dll", SetLastError = true)]
static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, uint reserved = 0);
public enum UDP_TABLE_CLASS
{
UDP_TABLE_BASIC,
UDP_TABLE_OWNER_PID,
UDP_TABLE_OWNER_MODULE
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDPTABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_UDPROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDPROW_OWNER_PID
{
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr); }
}
public ushort LocalPort
{
get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDP6TABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_UDP6ROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDP6ROW_OWNER_PID
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] localAddr;
public uint localScopeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr, localScopeId); }
}
public ushort LocalPort
{
get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
}
}
public static List<MIB_UDPROW_OWNER_PID> GetAllUDPConnections()
{
return GetUDPConnections<MIB_UDPROW_OWNER_PID, MIB_UDPTABLE_OWNER_PID> (AF_INET);
}
public static List<MIB_UDP6ROW_OWNER_PID> GetAllUDPv6Connections()
{
return GetUDPConnections<MIB_UDP6ROW_OWNER_PID, MIB_UDP6TABLE_OWNER_PID>(AF_INET6);
}
private static List<IPR> GetUDPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
{
List<IPR> result = null;
IPR[] tableRows = null;
int buffSize = 0;
var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");
// how much memory do we need?
uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
IntPtr udpTablePtr = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedUdpTable(udpTablePtr, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
if (ret != 0)
return new List<IPR>();
// get the number of entries in the table
IPT table = (IPT)Marshal.PtrToStructure(udpTablePtr, typeof(IPT));
int rowStructSize = Marshal.SizeOf(typeof(IPR));
uint numEntries = (uint)dwNumEntriesField.GetValue(table);
// buffer we will be returning
tableRows = new IPR[numEntries];
IntPtr rowPtr = (IntPtr)((long)udpTablePtr + 4);
for (int i = 0; i < numEntries; i++)
{
IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
tableRows[i] = tcpRow;
rowPtr = (IntPtr)((long)rowPtr + rowStructSize); // next entry
}
}
finally
{
result = tableRows?.ToList() ?? new List<IPR>();
// Free the Memory
Marshal.FreeHGlobal(udpTablePtr);
}
return result;
}
[DllImport("iphlpapi.dll", SetLastError = true)]
static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, uint reserved = 0);
public enum MIB_TCP_STATE
{
MIB_TCP_STATE_CLOSED = 1,
MIB_TCP_STATE_LISTEN = 2,
MIB_TCP_STATE_SYN_SENT = 3,
MIB_TCP_STATE_SYN_RCVD = 4,
MIB_TCP_STATE_ESTAB = 5,
MIB_TCP_STATE_FIN_WAIT1 = 6,
MIB_TCP_STATE_FIN_WAIT2 = 7,
MIB_TCP_STATE_CLOSE_WAIT = 8,
MIB_TCP_STATE_CLOSING = 9,
MIB_TCP_STATE_LAST_ACK = 10,
MIB_TCP_STATE_TIME_WAIT = 11,
MIB_TCP_STATE_DELETE_TCB = 12
}
public enum TCP_TABLE_CLASS
{
TCP_TABLE_BASIC_LISTENER,
TCP_TABLE_BASIC_CONNECTIONS,
TCP_TABLE_BASIC_ALL,
TCP_TABLE_OWNER_PID_LISTENER,
TCP_TABLE_OWNER_PID_CONNECTIONS,
TCP_TABLE_OWNER_PID_ALL,
TCP_TABLE_OWNER_MODULE_LISTENER,
TCP_TABLE_OWNER_MODULE_CONNECTIONS,
TCP_TABLE_OWNER_MODULE_ALL
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPTABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_TCPROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCP6TABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_TCP6ROW_OWNER_PID[] table;
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPROW_OWNER_PID
{
public uint state;
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint remoteAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] remotePort;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr); }
}
public ushort LocalPort
{
get
{
return BitConverter.ToUInt16(new byte[2] { localPort[1], localPort[0] }, 0);
}
}
public IPAddress RemoteAddress
{
get { return new IPAddress(remoteAddr); }
}
public ushort RemotePort
{
get
{
return BitConverter.ToUInt16(new byte[2] { remotePort[1], remotePort[0] }, 0);
}
}
public MIB_TCP_STATE State
{
get { return (MIB_TCP_STATE)state; }
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCP6ROW_OWNER_PID
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] localAddr;
public uint localScopeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] remoteAddr;
public uint remoteScopeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] remotePort;
public uint state;
public uint owningPid;
public uint ProcessId
{
get { return owningPid; }
}
public long LocalScopeId
{
get { return localScopeId; }
}
public IPAddress LocalAddress
{
get { return new IPAddress(localAddr, LocalScopeId); }
}
public ushort LocalPort
{
get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
}
public long RemoteScopeId
{
get { return remoteScopeId; }
}
public IPAddress RemoteAddress
{
get { return new IPAddress(remoteAddr, RemoteScopeId); }
}
public ushort RemotePort
{
get { return BitConverter.ToUInt16(remotePort.Take(2).Reverse().ToArray(), 0); }
}
public MIB_TCP_STATE State
{
get { return (MIB_TCP_STATE)state; }
}
}
public const int AF_INET = 2; // IP_v4 = System.Net.Sockets.AddressFamily.InterNetwork
public const int AF_INET6 = 23; // IP_v6 = System.Net.Sockets.AddressFamily.InterNetworkV6
public static Task<List<MIB_TCPROW_OWNER_PID>> GetAllTCPConnectionsAsync()
{
return Task.Run(() => GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET));
}
public static List<MIB_TCPROW_OWNER_PID> GetAllTCPConnections()
{
return GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET);
}
public static Task<List<MIB_TCP6ROW_OWNER_PID>> GetAllTCPv6ConnectionsAsync()
{
return Task.Run(()=>GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6));
}
public static List<MIB_TCP6ROW_OWNER_PID> GetAllTCPv6Connections()
{
return GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6);
}
private static List<IPR> GetTCPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
{
List<IPR> result = null;
IPR[] tableRows = null;
int buffSize = 0;
var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");
// how much memory do we need?
uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
IntPtr tcpTablePtr = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedTcpTable(tcpTablePtr, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
if (ret != 0)
return new List<IPR>();
// get the number of entries in the table
IPT table = (IPT)Marshal.PtrToStructure(tcpTablePtr, typeof(IPT));
int rowStructSize = Marshal.SizeOf(typeof(IPR));
uint numEntries = (uint)dwNumEntriesField.GetValue(table);
// buffer we will be returning
tableRows = new IPR[numEntries];
IntPtr rowPtr = (IntPtr)((long)tcpTablePtr + 4);
for (int i = 0; i < numEntries; i++)
{
IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
tableRows[i] = tcpRow;
rowPtr = (IntPtr)((long)rowPtr + rowStructSize); // next entry
}
}
finally
{
result = tableRows?.ToList() ?? new List<IPR>();
// Free the Memory
Marshal.FreeHGlobal(tcpTablePtr);
}
return result;
}
public static string GetTcpStateName(MIB_TCP_STATE state)
{
switch (state)
{
case MIB_TCP_STATE.MIB_TCP_STATE_CLOSED:
return "Closed";
case MIB_TCP_STATE.MIB_TCP_STATE_LISTEN:
return "Listen";
case MIB_TCP_STATE.MIB_TCP_STATE_SYN_SENT:
return "SynSent";
case MIB_TCP_STATE.MIB_TCP_STATE_SYN_RCVD:
return "SynReceived";
case MIB_TCP_STATE.MIB_TCP_STATE_ESTAB:
return "Established";
case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT1:
return "FinWait 1";
case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT2:
return "FinWait 2";
case MIB_TCP_STATE.MIB_TCP_STATE_CLOSE_WAIT:
return "CloseWait";
case MIB_TCP_STATE.MIB_TCP_STATE_CLOSING:
return "Closing";
case MIB_TCP_STATE.MIB_TCP_STATE_LAST_ACK:
return "LastAck";
case MIB_TCP_STATE.MIB_TCP_STATE_TIME_WAIT:
return "TimeWait";
case MIB_TCP_STATE.MIB_TCP_STATE_DELETE_TCB:
return "DeleteTCB";
default:
return ((int)state).ToString();
}
}
private static readonly ConcurrentDictionary<string, string> DicOfIpToHostName = new ConcurrentDictionary<string, string>();
public const string UnknownHostName = "Unknown";
// ******************************************************************
public static string GetHostName(IPAddress ipAddress)
{
return GetHostName(ipAddress.ToString());
}
// ******************************************************************
public static string GetHostName(string ipAddress)
{
string hostName = null;
if (!DicOfIpToHostName.TryGetValue(ipAddress, out hostName))
{
try
{
if (ipAddress == "0.0.0.0" || ipAddress == "::")
{
hostName = ipAddress;
}
else
{
hostName = Dns.GetHostEntry(ipAddress).HostName;
}
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
hostName = UnknownHostName;
}
DicOfIpToHostName[ipAddress] = hostName;
}
return hostName;
}
// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
List<NetworkInterface> candidates = new List<NetworkInterface>();
if (NetworkInterface.GetIsNetworkAvailable())
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (
NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
candidates.Add(ni);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
// Accoring to our tech, the main NetworkInterface should have a Gateway
// and it should be the ony one with a gateway.
if (candidates.Count > 1)
{
for (int n = candidates.Count - 1; n >= 0; n--)
{
if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
{
candidates.RemoveAt(n);
}
}
if (candidates.Count == 1)
{
return candidates[0];
}
}
// Fallback to try by getting my ipAdress from the dns
IPAddress myMainIpAdress = null;
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
{
myMainIpAdress = ip;
break;
}
}
if (myMainIpAdress != null)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.Address.Equals(myMainIpAdress))
{
return ni;
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4, AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
NetworkInterface[] NetworkInterfaces =
NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in NetworkInterfaces)
{
if (ni.GetPhysicalAddress().Equals(mac))
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
IPInterfaceProperties props = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
{
if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
{
if (ai.Address.AddressFamily == addressFamily)
{
return ai.Address;
}
}
}
}
}
}
return null;
}
// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
NetworkInterface ni = GetMainNetworkInterface();
IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
if (ipAddress == null) // could it be possible ?
{
ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
}
return ipAddress;
}
// ******************************************************************
public static bool IsBroadcastAddress(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
return ipAddress.GetAddressBytes()[3] == 255;
}
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return false; // NO broadcast in IPv6
}
return false;
}
// ******************************************************************
public static bool IsMulticastAddress(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
// Source: https://technet.microsoft.com/en-us/library/cc772041(v=ws.10).aspx
return ipAddress.GetAddressBytes()[0] >= 224 && ipAddress.GetAddressBytes()[0] <= 239;
}
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return ipAddress.IsIPv6Multicast;
}
return false;
}
// ******************************************************************
}
}
#24 楼
获取公共IP地址的另一种方法是使用带有resolve1.opendns.com
作为请求的OpenDNS myip.opendns.com
服务器。在命令行上,这是:
nslookup myip.opendns.com resolver1.opendns.com
或在C#中使用DNSClient nuget:
var lookup = new LookupClient(new IPAddress(new byte[] { 208, 67, 222, 222 }));
var result = lookup.Query("myip.opendns.com", QueryType.ANY);
这比击中http端点并解析响应要干净一些。
#25 楼
这是在VB.NET中以csv格式获取所有本地IP。Imports System.Net
Imports System.Net.Sockets
Function GetIPAddress() As String
Dim ipList As List(Of String) = New List(Of String)
Dim host As IPHostEntry
Dim localIP As String = "?"
host = Dns.GetHostEntry(Dns.GetHostName())
For Each ip As IPAddress In host.AddressList
If ip.AddressFamily = AddressFamily.InterNetwork Then
localIP = ip.ToString()
ipList.Add(localIP)
End If
Next
Dim ret As String = String.Join(",", ipList.ToArray)
Return ret
End Function
#26 楼
要获得最快的IP地址,可能是最快的方法。您必须必须使用下载程序,或在计算机上创建服务器。使用此简单代码的缺点:(建议使用)需要3-5秒才能获得Remote IP地址,因为WebClient初始化时总是需要3-5秒来检查您的代理设置。
public static string GetIP()
{
string externalIP = "";
externalIP = new WebClient().DownloadString("http://checkip.dyndns.org/");
externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
.Matches(externalIP)[0].ToString();
return externalIP;
}
这是我修复它的方法。.(第一次仍然需要3-5秒),但此后它将始终在0-2秒内获得您的远程IP地址,具体取决于您的连接。
public static WebClient webclient = new WebClient();
public static string GetIP()
{
string externalIP = "";
externalIP = webclient.DownloadString("http://checkip.dyndns.org/");
externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
.Matches(externalIP)[0].ToString();
return externalIP;
}
评论
为什么要投票?您无法找到比这个更快或更佳的答案。.每次初始化WebClient都没有很大的开销延迟。
– SSpoke
16 Mar 25 '16 at 0:19
评论
关于外部IP地址,我认为没有本地方法可以检索该地址。本地主机可能位于将本地网络地址转换为公共地址的NAT路由器后面。是否有(本地)方式来验证情况?我什么都不知道...该示例使用DNS获取IP地址,我曾经有过DNS错误信息的经验。对于这种情况,样本可能会以错误的信息进行响应。
@leiflundgren我也有DNS错误信息的经验。我的答案描述了在遇到这种情况时如何不依赖DNS就能获得所需的IP地址。
使用LINQ:Dns.GetHostEntry(Dns.GetHostName())。AddressList.Where(o => o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First()。ToString()
这是典型的情况,其中需求完全不同的用户往往会问相同的问题。有些人想知道如何从公共网络访问他们的计算机。规范答案是STUN,尽管许多答案都是依赖于随机第三方的骇客。有些人只想知道他们在本地网络上的IP地址。在这种情况下,好的答案是提到NetworkInterface.GetAllNetworkInterfaces方法。