gpt4 book ai didi

java - 在 Windows 平台上使用 Java 查找特定路由的传出 IP 地址

转载 作者:可可西里 更新时间:2023-11-01 02:42:32 24 4
gpt4 key购买 nike

虽然有很多线程使用 NetworkInterfaceInterfaceAddressInetAddress 的组合来查找机器 IP 地址,但我的情况是远不止于此。

我需要确定在与特定(给定)目标通信期间将使用的传出 IP 地址。我必须假设主机上可能有多个具有许多 IP 地址的接口(interface)。对于现实生活场景,这是我能想象到的最好的近似值,在这种情况下,我必须向仅通过 IP 地址知道的远程机器提供一个自己的 IP,它可以用来访问我的主机。

到目前为止,我还没有找到适合这项任务的纯 Java 解决方案。以我非常有限的 Java 知识,我认为没有简单的方法来分析可能的路由选项。这就是为什么在 Linux 上我将只在外部执行并解析类似的东西:

ip -o route get 10.10.xx.xx

这反过来会给我所需的值(“src xx.xx.xx.xx”):

10.10.xx.xx dev eth1  src 10.20.xx.xx \    cache  mtu 1500 advmss 1460 hoplimit 64

我的问题是是否有一种 native 方法可以在不调用上述外部命令的情况下实现相同的结果。如果不是,那么您对 ​​Windows 等效项有何建议?


我也尝试过使用 InetAddress.isReachable(...) 和外部 ping 给定的源地址,但前者在回退到 TCP 时在我的环境中的防火墙上失败回声,而另一个提供误报。 (在我的测试 VM 上,我有一个接口(interface)直接绑定(bind)到主机网络,第二个接口(interface)作为通过 VM 主机的桥接器 (NAT)。因此,对于 ping 两条路由,根据需要在相反的方向不支持通过主机的路由来执行此操作。)

如果有任何建议,我将不胜感激......

最佳答案

最后我得到了解析路由表(仅 IP4,没有静态路由)。这是一个代码片段,也许它对某人有用。更具体的路线优于更通用的路线。对于相同的网络部分长度,最佳度量获胜。

private static String findOutgoingIpForGivenAdress(String remoteIP) {
final String COMMAND = "route print -4";
List<RouteInfo> routes = new ArrayList<>();
try {
Process exec = Runtime.getRuntime().exec(COMMAND);
BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));

String localIP = null;
String line;
/* examples:
0.0.0.0 0.0.0.0 10.172.180.1 10.172.180.36 20
0.0.0.0 0.0.0.0 10.187.20.1 10.187.20.225 25
10.172.180.0 255.255.255.0 On-link 10.172.180.36 276
10.172.180.36 255.255.255.255 On-link 10.172.180.36 276
*/
Pattern p = Pattern.compile("^\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+\\S+?\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+(\\d+)\\s*$");
while ((line = reader.readLine()) != null) {
Matcher match = p.matcher(line);
if (match.matches()) {
String network = match.group(1);
String mask = match.group(2);
String address = match.group(3);
short maskLength = 0;
boolean networkMatch = network.contentEquals("0.0.0.0");
if (!networkMatch) {
SubnetUtils subnet = new SubnetUtils(network, mask);
SubnetUtils.SubnetInfo info = subnet.getInfo();
networkMatch = info.isInRange(remoteIP);
maskLength = Short.valueOf(info.getCidrSignature().split("/")[1]);
}
if (networkMatch) {
short metric = Short.valueOf(match.group(4));
routes.add(new RouteInfo(address, maskLength, metric));
}
}
}
Collections.sort(routes);
for (RouteInfo route : routes) {
}
if (!routes.isEmpty())
return routes.get(0).source;
if (localIP != null)
return localIP;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}

还有 RouteInfo 辅助类:

public class RouteInfo implements Comparable<RouteInfo> {
public final String source;
public final short maskLength;
public final short metric;

public RouteInfo(String src, short mask, short mtr) {
source = src;
maskLength = mask;
metric = mtr;
}

@Override
public int compareTo(RouteInfo ri) {
if (ri.maskLength != maskLength)
return ri.maskLength - maskLength;
return metric - ri.metric;
}
}

关于java - 在 Windows 平台上使用 Java 查找特定路由的传出 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32974080/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com