如何确定Java中路由器/网关的IP?

时间:2020-03-05 18:39:49  来源:igfitidea点击:

如何确定Java中路由器/网关的IP?我可以很容易地获得我的IP。我可以使用网站上的服务获取互联网IP。但是,如何确定网关的IP?

如果我们知道自己的方法,那么在.NET中这很容易。但是,我们如何用Java做到这一点呢?

解决方案

回答

那并不像听起来那么容易。 Java是平台无关的,因此我不确定如何在Java中进行操作。我猜想.NET与某个网站联系,将其报告回来。有两种方法。首先,深入研究ICMP协议可能会为我们提供所需的信息。我们还可以跟踪我们通过的IP(路由)。当我们遇到的IP不在以下范围内时:

  • 10.0.0.0 10.255.255.255
  • 172.16.0.0 172.31.255.255
  • 192.168.0.0 192.168.255.255

它是与IP相距一跳的IP,并且可能与IP共享几个八位字节的信息。

祝你好运。我很想听到这个问题的确切答案。

回答

如果有,请尝试脱壳到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

解析第二行。是的,这很丑陋,但除非有人发布更好的内容,否则它会让我们继续前进。

回答

使用checkmyip.org之类的东西可能会更好,它可以确定公共IP地址,不一定是第一跳路由器:在Uni,我有一个"真实" IP地址,而在家里,这是我本地路由器的公共IP地址。

我们可以解析返回的页面,或者找到另一个站点,该站点允许我们仅将IP地址作为唯一字符串取回。

(我的意思是用Java /任何方式加载此URL,然后获取所需的信息)。

这应该完全独立于平台。

回答

马修:是的,这就是我的意思,"我可以使用网站上的服务获取互联网IP"。很抱歉成为glib。

Brian / Nick:Traceroute会很好,除非这些路由器中有许多禁用了ICMP,因此它总是停滞。

我认为将traceroute和uPnP结合使用是可行的。那就是我打算做的事情,只是希望我遗漏了一些明显的东西。

谢谢大家的评论,所以听起来我似乎没有任何明显的缺失。我已经开始实现uPnP的一些功能以发现网关。

回答

不幸的是,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();"以使令牌生成器再增加一个位置。

回答

关于UPnP:请注意,并非所有路由器都支持UPnP。如果这样做,则可以将其关闭(出于安全原因)。因此,解决方案可能并不总是有效。

我们还应该看看NatPMP。

可以在http://miniupnp.free.fr/找到一个简单的UPnP库,尽管它在C语言中。

回答

为了克服traceroute提到的问题(基于ICMP的广域网攻击),我们可以考虑:

  • 跟踪到公共IP的路由(避免广域网攻击,但仍然是ICMP)
  • 使用非ICMP实用程序,如ifconfig / ipconfig(尽管与此相关的可移植性问题)。
  • 目前看来,最好,最便携的解决方案是对netstat进行外壳和解析(请参见此处的代码示例)

回答

在Windows上,解析IPConfig的输出将为我们提供默认网关,而无需等待跟踪。

回答

在Windows,OSX,Linux等系统上,Chris Bunch的答案可以通过使用来大大改善

netstat -rn

代替traceroute命令。

网关的IP地址将出现在以" default"或者" 0.0.0.0"开头的行的第二个字段中。

尝试使用traceroute可以解决许多问题:

  • 在Windows上," traceroute"实际上是" tracert.exe",因此代码中不需要O / S依赖项
  • 这是一个快速运行的命令-它从操作系统(而不是网络)获取信息
  • traceroute有时会被网络阻止

唯一的缺点是必须保持从netstat输出中读取行,直到找到正确的行为止,因为会有多行输出。

编辑:如果我们使用的是MAC(在Lion上测试),则默认网关的IP地址位于以"默认"开头的行的第二个字段中,或者位于以" 0.0.0.0"开头的行的第三个字段中(在Windows 7上测试)

视窗:

Network Destination        Netmask          Gateway       Interface  Metric
    
    0.0.0.0              0.0.0.0    192.168.2.254     192.168.2.46     10

苹果电脑:

Destination        Gateway            Flags        Refs      Use   Netif Expire
    
    default            192.168.2.254      UGSc          104        4     en1

回答

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

回答

我们可以查询URL" 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();
        }
    }

回答

netstat -rn的输出是特定于语言环境的。
在我的系统(locale = de)上,输出如下所示:
...
标准网关:10.22.0.1

因此,没有以" default"开头的行。

因此使用netstat可能不是一个好主意。