Java Socket 无法使用 NoRouteToHostException 而不是 ConnectionRefused 连接到 "0.0.0.0"

标签 java python sockets networking linux-kernel

问题

打开到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.0127.0.0.1在源代码中解决了 问题,和 ConnectionRefused (预期)被提高而不是 NoRouteToHostException
  • 禁用 Firewalld、禁用 SELinux 等

问题

  1. 这是 Java 错误吗?如果是这样,为什么它在 Machine2 上工作,即使 他们使用相同的 jdk 和相同的 java 版本?
  2. 这是 Linux 内核错误吗?如果是这样,为什么当我打开它时它与 Python 一起工作 一个套接字到 0.0.0.0 但不是 java?我会假设潜在的 系统调用是相同的。

澄清

在上面的示例中,我使用了一个关闭的端口,仅用于演示目的。如果机器上有一个实际的监听端口,这同样适用,那么它将是 ConnectionRefused对比SUCCESS

最佳答案

0.0.0.0special 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/

相关文章:

java - 删除eclipse中的双倍间距

java - 使用 Transport=dt_shmem 在 Eclipse 中调试 Java 应用程序

java - 方法 replace(String, ArrayList<>) 未定义 HashMap 类型

Java:从 JInternalFrame 获取 Mainform 对象

python - 图例有多个点

python - 简单的 python 嵌套循环 - 索引超出范围

node.js - 如何使用路径创建套接字连接

c++ - Bug 保活延迟

python - 在 Linux 上为 Kivy 游戏的每个支持平台创建安装程序或可执行文件

C使用sendto发送多种数据类型