如何在Java中确定路由器/网关的IP?我可以轻松地获得我的IP。我可以使用网站上的服务获取我的互联网IP。但是如何确定网关的IP?
如果你了解自己的方式,这在.NET中有点容易。但是你如何用Java做到这一点?
答案 0 :(得分:23)
在Windows,OSX,Linux等上,使用
可以大大改善Chris Bunch的答案netstat -rn
代替traceroute
命令。
您网关的IP地址将显示在以default
或0.0.0.0
开头的行的第二个字段中。
尝试使用traceroute
时会遇到很多问题:
traceroute
实际上是tracert.exe
,因此代码中不需要O / S依赖traceroute
有时被网络阻止唯一的缺点是有必要继续从netstat
输出读取行直到找到右行,因为输出行不止一行。
编辑:默认网关的IP地址位于以“默认”开头的行的第二个字段中(如果您在MAC上测试)或在第三个字段中以“0.0.0.0”开头的行的字段(在Windows 7上测试)
视窗:
网络目标网络掩码网关接口指标
0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10
的Mac:
目标网关标志参考使用Netif Expire
默认 192.168.2.254 UGSc 104 4 en1
答案 1 :(得分:10)
遗憾的是,Java并没有像其他语言那样令人愉快。这是我做的:
import java.io.*;
import java.util.*;
public class ExecTest {
public static void main(String[] args) throws IOException {
Process result = Runtime.getRuntime().exec("traceroute -m 1 www.amazon.com");
BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
String thisLine = output.readLine();
StringTokenizer st = new StringTokenizer(thisLine);
st.nextToken();
String gateway = st.nextToken();
System.out.printf("The gateway is %s\n", gateway);
}
}
这假定网关是第二个令牌而不是第三个令牌。如果是,则需要添加额外的st.nextToken();
以使标记器再推进一次。
答案 2 :(得分:4)
try{
Process result = Runtime.getRuntime().exec("netstat -rn");
BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
String line = output.readLine();
while(line != null){
if ( line.startsWith("default") == true )
break;
line = output.readLine();
}
StringTokenizer st = new StringTokenizer( line );
st.nextToken();
gateway = st.nextToken();
st.nextToken();
st.nextToken();
st.nextToken();
adapter = st.nextToken();
} catch( Exception e ) {
System.out.println( e.toString() );
gateway = new String();
adapter = new String();
}
答案 3 :(得分:3)
在Windows上解析IPConfig的输出将获得默认网关,而无需等待跟踪。
答案 4 :(得分:2)
你可能最好使用像checkmyip.org这样的东西来确定你的公共IP地址 - 不一定是你的第一跳路由器:在Uni我有一个“真正的”IP地址,而在家里它是我的本地路由器的公共IP地址。
您可以解析返回的页面,或者找到另一个允许您将IP地址作为唯一字符串返回的网站。
(我的意思是在Java /中加载此URL,然后获取您需要的信息)。
这应该完全独立于平台。
答案 5 :(得分:2)
关于UPnP:请注意并非所有路由器都支持UPnP。如果他们这样做,可以关闭(出于安全原因)。所以你的解决方案可能并不总是有效。
您还应该看看NatPMP。
UPnP的一个简单库可以在http://miniupnp.free.fr/找到,虽然它在C ...
答案 6 :(得分:2)
要克服traceroute(基于ICMP,广域命中)提到的问题,您可以考虑:
答案 7 :(得分:2)
netstat -rn的输出是特定于语言环境的。 在我的系统(locale = de)上输出如下: ... Standardgateway:10.22.0.1
所以没有以'default'开头的行。
所以使用netstat可能不是一个好主意。
答案 8 :(得分:2)
此版本连接到www.whatismyip.com,读取网站内容并通过正则表达式搜索ip地址并将其打印到cmd。它对MosheElishas代码有一点改进
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
BufferedReader buffer = null;
try {
URL url = new URL(
"http://www.whatismyip.com/tools/ip-address-lookup.asp");
InputStreamReader in = new InputStreamReader(url.openStream());
buffer = new BufferedReader(in);
String line = buffer.readLine();
Pattern pattern = Pattern
.compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
Matcher matcher;
while (line != null) {
matcher = pattern.matcher(line);
if (matcher.matches()) {
line = matcher.group(2) + "." + matcher.group(3) + "."
+ matcher.group(4) + "." + matcher.group(5);
System.out.println(line);
}
line = buffer.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
BufferedReader buffer = null;
try {
URL url = new URL(
"http://www.whatismyip.com/tools/ip-address-lookup.asp");
InputStreamReader in = new InputStreamReader(url.openStream());
buffer = new BufferedReader(in);
String line = buffer.readLine();
Pattern pattern = Pattern
.compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
Matcher matcher;
while (line != null) {
matcher = pattern.matcher(line);
if (matcher.matches()) {
line = matcher.group(2) + "." + matcher.group(3) + "."
+ matcher.group(4) + "." + matcher.group(5);
System.out.println(line);
}
line = buffer.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
答案 9 :(得分:1)
这并不像听起来那么容易。 Java是独立于平台的,因此我不确定如何在Java中实现它。我猜测 .NET联系了一些报告它的网站。有几种方法可以去。首先,深入了解ICMP协议可能会为您提供所需的信息。您还可以跟踪您经历的IP(您的路线)。当您遇到不在以下范围内的IP时:
它是距离您的IP一跳的IP,并且可能与您的IP共享几个八位字节的信息。
祝你好运。我很想知道这个问题的确切答案。答案 10 :(得分:1)
尝试使用traceroute进行追踪,如果有的话。
'traceroute -m 1 www.amazon.com'会发出类似这样的信息:
traceroute to www.amazon.com (72.21.203.1), 1 hops max, 40 byte packets
1 10.0.1.1 (10.0.1.1) 0.694 ms 0.445 ms 0.398 ms
解析第二行。是的,这很丑陋,但它会让你去,直到有人发布更好的东西。
答案 11 :(得分:1)
Brian / Nick:Traceroute没问题,因为很多这些路由器都禁用了ICMP,因此它总是停滞不前。
我认为traceroute和uPnP的组合将会成功。这就是我计划做的事情,我只是希望我遗漏了一些明显的东西。
感谢大家的评论,所以听起来我没有遗漏任何明显的东西。我已经开始实现一些uPnP来发现网关。
答案 12 :(得分:1)
您可以查询网址“http://whatismyip.com/automation/n09230945.asp”。 例如:
BufferedReader buffer = null;
try {
URL url = new URL("http://whatismyip.com/automation/n09230945.asp");
InputStreamReader in = new InputStreamReader(url.openStream());
buffer = new BufferedReader(in);
String line = buffer.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
答案 13 :(得分:1)
在Windows中,您只需使用以下命令:
ipconfig | findstr /i "Gateway"
这将为您提供如下输出:
Default Gateway . . . . . . . . . : 192.168.2.1
Default Gateway . . . . . . . . . : ::
但是我不能用Java运行这个命令,当我想出来的时候会发布。
答案 14 :(得分:1)
您可以使用Windows,OSX,Linux等平台上提供的netstat -rn
命令。这是我的代码:
private String getDefaultAddress() {
String defaultAddress = "";
try {
Process result = Runtime.getRuntime().exec("netstat -rn");
BufferedReader output = new BufferedReader(new InputStreamReader(
result.getInputStream()));
String line = output.readLine();
while (line != null) {
if (line.contains("0.0.0.0")) {
StringTokenizer stringTokenizer = new StringTokenizer(line);
stringTokenizer.nextElement(); // first element is 0.0.0.0
stringTokenizer.nextElement(); // second element is 0.0.0.0
defaultAddress = (String) stringTokenizer.nextElement();
break;
}
line = output.readLine();
} // while
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return defaultAddress;
} // getDefaultAddress
答案 15 :(得分:0)
我不确定它是否适用于每个系统,但至少在这里我发现了这一点:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main
{
public static void main(String[] args)
{
try
{
//Variables to find out the Default Gateway IP(s)
String canonicalHostName = InetAddress.getLocalHost().getCanonicalHostName();
String hostName = InetAddress.getLocalHost().getHostName();
//"subtract" the hostName from the canonicalHostName, +1 due to the "." in there
String defaultGatewayLeftover = canonicalHostName.substring(hostName.length() + 1);
//Info printouts
System.out.println("Info:\nCanonical Host Name: " + canonicalHostName + "\nHost Name: " + hostName + "\nDefault Gateway Leftover: " + defaultGatewayLeftover + "\n");
System.out.println("Default Gateway Addresses:\n" + printAddresses(InetAddress.getAllByName(defaultGatewayLeftover)));
} catch (UnknownHostException e)
{
e.printStackTrace();
}
}
//simple combined string out of the address array
private static String printAddresses(InetAddress[] allByName)
{
if (allByName.length == 0)
{
return "";
} else
{
String str = "";
int i = 0;
while (i < allByName.length - 1)
{
str += allByName[i] + "\n";
i++;
}
return str + allByName[i];
}
}
}
对我来说,这产生了:
Info:
Canonical Host Name: PCK4D-PC.speedport.ip
Host Name: PCK4D-PC
Default Gateway Leftover: speedport.ip
Default Gateway Addresses:
speedport.ip/192.168.2.1
speedport.ip/fe80:0:0:0:0:0:0:1%12
我需要在其他系统/配置/ PC-网关-设置上进行更多测试,以确认它是否可以在所有地方使用。有点怀疑,但这是我发现的第一个。