当使用Java的套接字类向IP: 0.0.0.0
和Port: 37845
(只是一个随机关闭的端口)打开套接字时,套接字连接失败,并且在机器1上出现java.net.NoRouteToHostException
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)
Machine1:
[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
Machine2:
[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))
127.0.0.1
0.0.0.0
替换127.0.0.1
可解决
问题,并且引发ConnectionRefused
(预期)而不是NoRouteToHostException
在上面的示例中,我使用了一个封闭的端口,仅用于演示目的。如果机器上有实际的侦听端口,则同样适用,则将是ConnectionRefused
与SUCCESS
答案 0 :(得分:6)
0.0.0.0
是special address,属于特殊0.0.0.0/8
范围的一部分,表示“当前网络”或“未指定”。您无法连接到它,因为它未定义为目的地。
这就是为什么您得到NoRouteToHostException
的原因-地址根本无法路由。如果尝试运行ping 0.0.0.0
或类似的命令,也会遇到类似的失败。
ConnectionRefused
发生在远程计算机实际上拒绝连接时,这通常表明该远程计算机没有侦听套接字或位于防火墙后面。
答案 1 :(得分:2)
我肯定会在两台计算机上都安装Wireshark,并比较所有方案。
特别是:
https://superuser.com/questions/720851/connection-refused-vs-no-route-to-host
“连接被拒绝”表示目标计算机主动拒绝了连接...以下原因之一可能是原因:
- 端口上没有监听
- 防火墙阻止了与REJECT的连接
ICMP消息“没有到主机的路由”表示ARP无法找到 目标主机的第二层地址。通常,这意味着 具有该IP地址的主机不在线或没有响应。
当然,这引出了一个问题,为什么Python在同一台机器上表现为一种方式而Java却表现出不同的方式。
再次-我鼓励您看看Wireshark。特别是,请看一下1)三向TCP握手,以及2)在其之前的ARP调用。
PS:正如麦芽所说:
0.0.0.0 ...地址根本无法路由。
在Windows上,您可能会得到 WSAEADDRNOTAVAIL -The remote address is not a valid address
请问一个问题,为什么您会收到“ ConnectionRefused”。
再次-我很好奇Wireshark向您显示什么。
答案 2 :(得分:0)
我内联了您提供的代码,并在Windows 10系统上运行它,我得到了正确的异常
import java.net.InetSocketAddress;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws Exception {
new Socket().connect(new InetSocketAddress("0.0.0.0", 37845), 10_0000);
}
}
Oracle JDK 8.0.202
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
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.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at Main.main(Main.java:8)
Process finished with exit code 1