问题
打开到IP: 0.0.0.0
的套接字时和 Port: 37845
(只是一个随机关闭的端口)与 java 的套接字类,套接字连接失败并显示 java.net.NoRouteToHostException
在机器 1
Exception in thread "main" java.net.NoRouteToHostException: No route to host (Host unreachable)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:204)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at Test.main(Test.java:26)
我正在使用这个测试代码:
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
public class Test {
public static void main(String[] args) throws Exception {
Socket socket;
// create a socket with a timeout
SocketAddress socketAddress = new InetSocketAddress("0.0.0.0", 37845);
// create a socket
socket = new Socket();
// this method will block no more than timeout ms.
int timeoutInMs = 10 * 1000; // 10 seconds
socket.connect(socketAddress, timeoutInMs);
System.err.println("SUCCESS");
}
}
预计
什么,我实际上期待的是 java.net.ConnectException : Connection refused (Connection refused)
,这也是我在另一台 Cent OS 机器上得到的,我们称它为 Machine2:
Exception in thread "main" java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:204)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at Test.main(Test.java:26)
设置
机器 1:
[qa@jenkins-staging ~]$ cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)
[qa@jenkins-staging ~]$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
[qa@jenkins-staging ~]$ uname -a
Linux jenkins-staging.fancydomain 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
机器 2:
[qa@localhost ~]$ cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)
[qa@localhost ~]$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
[qa@localhost ~]$ uname -a
Linux localhost.localdomain 3.10.0-957.1.3.el7.x86_64 #1 SMP Thu Nov 29 14:49:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
所以看起来唯一的区别是内核版本。
我尝试过的其他事情:
我用 python 尝试了“相同”的代码,我总是得到一个
ConnectionRefused
(在 Machine1 + Machine2 上)import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("0.0.0.0", 37845))
- 在 Machine1 上 Ping 0.0.0.0 也能正常工作并解析为
127.0.0.1
- 替换
0.0.0.0
与127.0.0.1
在源代码中解决了 问题,和ConnectionRefused
(预期)被提高而不是NoRouteToHostException
- 禁用 Firewalld、禁用 SELinux 等
问题
- 这是 Java 错误吗?如果是这样,为什么它在 Machine2 上工作,即使 他们使用相同的 jdk 和相同的 java 版本?
- 这是 Linux 内核错误吗?如果是这样,为什么当我打开它时它与 Python 一起工作 一个套接字到 0.0.0.0 但不是 java?我会假设潜在的 系统调用是相同的。
澄清
在上面的示例中,我使用了一个关闭的端口,仅用于演示目的。如果机器上有一个实际的监听端口,这同样适用,那么它将是 ConnectionRefused
对比SUCCESS
最佳答案
0.0.0.0
是 special address ,特殊 0.0.0.0/8
范围的一部分,表示“当前网络”或“未指定”。您无法连接到它,因为它未定义为目的地。
这就是您收到 NoRouteToHostException
的原因 - 地址根本无法路由。如果您尝试运行 ping 0.0.0.0
或类似的命令,您将遇到类似的失败。
ConnectionRefused
发生在远程机器实际上拒绝连接时,这通常表明远程机器没有监听套接字或位于防火墙后面。
关于Java Socket 无法使用 NoRouteToHostException 而不是 ConnectionRefused 连接到 "0.0.0.0",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54636989/