gpt4 book ai didi

java - 由 NodeJS 生成的 Java 进程中网络接口(interface)的 IP 地址

转载 作者:行者123 更新时间:2023-11-30 08:43:40 27 4
gpt4 key购买 nike

由 NodeJS 启动的 Java 进程似乎无法检测网络接口(interface)的 IPv6 地址。考虑以下 java 代码:

public class ListAddresses {
public static void main(String args[]) throws SocketException {
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(nets))
displayInterfaceInformation(netint);
}

static void displayInterfaceInformation(NetworkInterface netint)

throws SocketException {
out.printf("Display name: %s\n", netint.getDisplayName());
out.printf("Name: %s\n", netint.getName());
Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
for (InetAddress inetAddress : Collections.list(inetAddresses)) {
out.printf("InetAddress: %s\n", inetAddress);
}
out.printf("\n");
}
}

如果我从命令行运行它,它会打印以下内容:

Display name: wlan0
Name: wlan0
InetAddress: /fe80:0:0:0:6e88:14ff:fe67:8130%3
InetAddress: /192.168.1.102

Display name: lo
Name: lo
InetAddress: /0:0:0:0:0:0:0:1%1
InetAddress: /127.0.0.1

如果我像这样从 NodeJS 中启动它:

var spawn = require('child_process').spawn;
var prc = spawn('java', ['ListAddresses']);

prc.stdout.on('data', function (data) {
console.log('' + data);
});

那么它的输出是:

Display name: 
wlan0
Name: wlan0
InetAddress: /192.168.1.102

Display name: lo
Name: lo
InetAddress: /127.0.0.1

因此缺少 IPv6 地址。最后,如果我将生成方式更改为:

var prc = spawn('java', ['ListAddresses'], { stdio: [ 'ignore', null, null] });

然后启动的 java 进程正确地打印所有 IP 地址(这似乎与 https://stackoverflow.com/a/22950304/594406 有某种关系,但我不知道如何)。有人知道发生了什么事吗?我在 Ubuntu 14.04.3 LTS 上使用 java 1.8.0_66 和 node v4.2.2。请注意,父 NodeJS 进程会检测 IPv6 地址,如果我启动 NodeJS 子进程,那么它也会检测到它们。

最佳答案

这可能有点晚了,但我今天遇到了同样的问题,并进一步调查了一下。

这实际上不是 Node.js 问题,而是一些奇怪的 JVM 行为。原始帖子中的解决方法帮助我找到了根本原因:如果您不将 'ignore' 作为 stdio 数组中的第一个条目传递,将生成子进程使用绑定(bind)到文件描述符 0(又名标准输入)的 unix 域套接字。

JVM 具有检测是否支持 IPv6 的功能,其中包括以下检查 piece of code .该代码与上面评论中的描述不符。因此,当套接字绑定(bind)到 fd 0 且其类型不是 IPv6 套接字时,该实现实际上禁用了 IPv6。因此,当 Node.js 将 unix 套接字绑定(bind)到 fd 0 时,IPv6 也会被禁用。

/*
* If fd 0 is a socket it means we've been launched from inetd or
* xinetd. If it's a socket then check the family - if it's an
* IPv4 socket then we need to disable IPv6.
*/
if (getsockname(0, &sa.sa, &sa_len) == 0) {
if (sa.sa.sa_family != AF_INET6) {
close(fd);
return JNI_FALSE;
}
}

我将此作为一个错误报告给了 Java 错误数据库,但由于这段代码已经存在很长时间了,所以它可能不会被优先修复(或者这甚至可能是有意的?)。

更新:该问题现已确认为错误,现在可以在 Java Bug Tracker 中看到.

关于java - 由 NodeJS 生成的 Java 进程中网络接口(interface)的 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34108124/

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