想象一下这种情况,我有两台局域网的PC,一台连接到互联网另一台连接到本地网络,如何通过C#检测连接到互联网的IP?
答案 0 :(得分:13)
试试这个:
static IPAddress getInternetIPAddress()
{
try
{
IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());
IPAddress gateway = IPAddress.Parse(getInternetGateway());
return findMatch(addresses, gateway);
}
catch (FormatException e) { return null; }
}
static string getInternetGateway()
{
using (Process tracert = new Process())
{
ProcessStartInfo startInfo = tracert.StartInfo;
startInfo.FileName = "tracert.exe";
startInfo.Arguments = "-h 1 208.77.188.166"; // www.example.com
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
tracert.Start();
using (StreamReader reader = tracert.StandardOutput)
{
string line = "";
for (int i = 0; i < 9; ++i)
line = reader.ReadLine();
line = line.Trim();
return line.Substring(line.LastIndexOf(' ') + 1);
}
}
}
static IPAddress findMatch(IPAddress[] addresses, IPAddress gateway)
{
byte[] gatewayBytes = gateway.GetAddressBytes();
foreach (IPAddress ip in addresses)
{
byte[] ipBytes = ip.GetAddressBytes();
if (ipBytes[0] == gatewayBytes[0]
&& ipBytes[1] == gatewayBytes[1]
&& ipBytes[2] == gatewayBytes[2])
{
return ip;
}
}
return null;
}
请注意,findMatch()
的此实现依赖于C类匹配。如果您想支持B类匹配,只需省略对ipBytes[2] == gatewayBytes[2]
。
修改历史记录:
www.example.com
。getInternetIPAddress()
,以说明如何使用其他方法。FormatException
无法解析网关IP,则更新以捕获getInternetGateway()
。 (如果配置网关路由器使其不响应traceroute请求,则会发生这种情况。)答案 1 :(得分:9)
互联网连接必须与默认网关位于同一IP网络上。
如果你能够到达“互联网”,那么无法从IP地址告诉我。基本上,您可以与自己的IP网络进行通信。其他一切都必须通过网关。因此,如果您看不到网关,则仅限于本地IP网络。
然而,网关依赖于其他网关,因此即使您可以访问网关,也可能无法访问其他网络。这可能是由于例如过滤或缺少到所需网络的路由。
实际上,从这个意义上谈论互联网是没有意义的,因为在任何特定时刻你可能永远无法访问整个互联网。因此,找出您需要能够访问和验证该网络的连接。
答案 2 :(得分:8)
我建议使用这个简单的代码,因为tracert
并不总是有效,而且whatsmyip.com不是专门为此目的设计的:
private void GetIP()
{
WebClient wc = new WebClient();
string strIP = wc.DownloadString("http://checkip.dyndns.org");
strIP = (new Regex(@"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")).Match(strIP).Value;
wc.Dispose();
return strIP;
}
答案 3 :(得分:6)
这是我尝试获取默认IPv4地址而不必求助于DNS或外部进程调用ipconfig和route等命令。希望下一版本的.Net能够访问Windows路由表。
public static IPAddress GetDefaultIPv4Address()
{
var adapters = from adapter in NetworkInterface.GetAllNetworkInterfaces()
where adapter.OperationalStatus == OperationalStatus.Up &&
adapter.Supports(NetworkInterfaceComponent.IPv4)
&& adapter.GetIPProperties().GatewayAddresses.Count > 0 &&
adapter.GetIPProperties().GatewayAddresses[0].Address.ToString() != "0.0.0.0"
select adapter;
if (adapters.Count() > 1)
{
throw new ApplicationException("The default IPv4 address could not be determined as there are two interfaces with gateways.");
}
else
{
UnicastIPAddressInformationCollection localIPs = adapters.First().GetIPProperties().UnicastAddresses;
foreach (UnicastIPAddressInformation localIP in localIPs)
{
if (localIP.Address.AddressFamily == AddressFamily.InterNetwork &&
!localIP.Address.ToString().StartsWith(LINK_LOCAL_BLOCK_PREFIX) &&
!IPAddress.IsLoopback(localIP.Address))
{
return localIP.Address;
}
}
}
return null;
}
答案 4 :(得分:2)
一种愚蠢的方式是获取并抓取许多“我的IP是什么”类型网站中的一个。
答案 5 :(得分:2)
不是100%准确(某些ISP不提供公共IP地址),但您可以检查IP地址是否在为私有地址保留的范围之一。见http://en.wikipedia.org/wiki/Classful_network
答案 6 :(得分:1)
以下是一篇可能有用的文章:
How to Retrieve "Network Interfaces" in C#
以下代码用于检索 C#中的“网络接口”。您 可能会认出“网络接口” 作为“网络和拨号连接”: 您可以使用以下方式访问它们 “开始&gt;设置&gt;网络和拨号连接”。 C#没有提供 检索此列表的简单方法。
答案 7 :(得分:1)
我找到了解决方案:
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
Console.WriteLine(ipProperties.HostName);
foreach (NetworkInterface networkCard in NetworkInterface.GetAllNetworkInterfaces())
{
foreach (GatewayIPAddressInformation gatewayAddr in networkCard.GetIPProperties().GatewayAddresses)
{
Console.WriteLine("Information: ");
Console.WriteLine("Interface type: {0}", networkCard.NetworkInterfaceType.ToString());
Console.WriteLine("Name: {0}", networkCard.Name);
Console.WriteLine("Id: {0}", networkCard.Id);
Console.WriteLine("Description: {0}", networkCard.Description);
Console.WriteLine("Gateway address: {0}", gatewayAddr.Address.ToString());
Console.WriteLine("IP: {0}", System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName()).AddressList[0].ToString());
Console.WriteLine("Speed: {0}", networkCard.Speed);
Console.WriteLine("MAC: {0}", networkCard.GetPhysicalAddress().ToString());
}
}
答案 8 :(得分:0)
我已经搜索过了,我在这个codeplex项目http://www.codeplex.com/xedus中找到了它。 它是一个无法工作的P2P免费软件,但是有一个类使用正确的API来获取lan卡巫婆有互联网IP
答案 9 :(得分:0)
对于快速入侵(通过精心设计的LAN配置或IPv6肯定会破坏),获取当前计算机所有IP的列表,并删除所有符合以下任何内容的IP:
10.* 127.* // <- Kudos to Brian for spotting the mistake 172.[16-31].* 192.168.*
答案 10 :(得分:0)
使用tracert。第一跳应始终与您的Internet NIC位于同一子网上。
来自命令提示符的示例。
tracert google.com
第一行是10.0.0.254,我的网站的IP是10.0.2.48。然后,这是一个解析tracert输出的简单练习。
答案 11 :(得分:0)
另一种解决方案(可能更准确)是使用Windows route
命令。以下是一些适用于Windows Vista的代码:
static string getInternetConnectionIP()
{
using (Process route = new Process())
{
ProcessStartInfo startInfo = route.StartInfo;
startInfo.FileName = "route.exe";
startInfo.Arguments = "print 0.0.0.0";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
route.Start();
using (StreamReader reader = route.StandardOutput)
{
string line;
do
{
line = reader.ReadLine();
} while (!line.StartsWith(" 0.0.0.0"));
// the interface is the fourth entry in the line
return line.Split(new char[] { ' ' },
StringSplitOptions.RemoveEmptyEntries)[3];
}
}
}
答案 12 :(得分:0)
和我的朋友LukasŠalkauskas一样,我写了这段代码:
/* digged, built and (here and there) copied "as is" from web, without paying attention to style.
Please, do not shot us for this.
*/
public static void DisplayIPAddresses()
{
Console.WriteLine("\r\n****************************");
Console.WriteLine(" IPAddresses");
Console.WriteLine("****************************");
StringBuilder sb = new StringBuilder();
// Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface network in networkInterfaces)
{
if (network.OperationalStatus == OperationalStatus.Up )
{
if (network.NetworkInterfaceType == NetworkInterfaceType.Tunnel) continue;
if (network.NetworkInterfaceType == NetworkInterfaceType.Tunnel) continue;
//GatewayIPAddressInformationCollection GATE = network.GetIPProperties().GatewayAddresses;
// Read the IP configuration for each network
IPInterfaceProperties properties = network.GetIPProperties();
//discard those who do not have a real gateaway
if (properties.GatewayAddresses.Count > 0)
{
bool good = false;
foreach (GatewayIPAddressInformation gInfo in properties.GatewayAddresses)
{
//not a true gateaway (VmWare Lan)
if (!gInfo.Address.ToString().Equals("0.0.0.0"))
{
sb.AppendLine(" GATEAWAY "+ gInfo.Address.ToString());
good = true;
break;
}
}
if (!good)
{
continue;
}
}
else {
continue;
}
// Each network interface may have multiple IP addresses
foreach (IPAddressInformation address in properties.UnicastAddresses)
{
// We're only interested in IPv4 addresses for now
if (address.Address.AddressFamily != AddressFamily.InterNetwork) continue;
// Ignore loopback addresses (e.g., 127.0.0.1)
if (IPAddress.IsLoopback(address.Address)) continue;
if (!address.IsDnsEligible) continue;
if (address.IsTransient) continue;
sb.AppendLine(address.Address.ToString() + " (" + network.Name + ") nType:" + network.NetworkInterfaceType.ToString() );
}
}
}
Console.WriteLine(sb.ToString());
}
答案 13 :(得分:-1)
尝试在两个界面上ping www.google.com。
答案 14 :(得分:-1)
您只需阅读http://myip.dnsomatic.com/
即可这是OpenDNS提供的可靠服务,我一直用它来获取外部IP。