Reputation: 383
When opening a socket to IP: 0.0.0.0
and Port: 37845
(just a random closed port) with java's socket class , the socket connect fails with a java.net.NoRouteToHostException
on Machine 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)
I'm using this testcode:
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");
}
}
What , I'm actually expecting is a java.net.ConnectException : Connection refused (Connection refused)
, which is also what I'm getting with another Cent OS machine, let's call it 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
So it seems like the only difference is the kernel version.
I tried the "same" code with python , there i always get a
ConnectionRefused
(on 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
with 127.0.0.1
in the source code resolves the
problem , and ConnectionRefused
(expected) is raised instead of NoRouteToHostException
In the example above i used a port which is closed , just for demonstration purposes. The same applies if there is an actual listening port on the machine then it will be ConnectionRefused
vs SUCCESS
Upvotes: 8
Views: 2574
Reputation: 865
I inlined the Code you provided and run it on windows 10 system, i get the correct exception
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
Upvotes: 0
Reputation: 121759
I would definitely install Wireshark on both machines, and compare all scenarios.
Specifically:
https://superuser.com/questions/720851/connection-refused-vs-no-route-to-host
"Connection refused" means that the target machine actively rejected the connection... one of the following things is likely the reason:
- Nothing is listening on the port
- The firewall is blocking the connection with REJECT
The ICMP message, "no route to host," means that ARP cannot find the layer-2 address for the destination host. Usually, this means that that the host with that IP address is not online or responding.
Of course, this begs the question why Python behaves one way, and Java a different way ... on the same machine.
Again - I'd encourage you to look at Wireshark. In particular, look at 1) the three-way TCP handshake, and 2) the ARP call that precedes it.
PS: As malt says above:
0.0.0.0 ... the address is simply not routable.
On Windows, you might get WSAEADDRNOTAVAIL -The remote address is not a valid address
Which begs the question why you're ever getting "ConnectionRefused".
Again - I'm definitely curious what Wireshark shows you.
Upvotes: 1
Reputation: 30335
0.0.0.0
is a special address, part of the special 0.0.0.0/8
range that means "current network" or "unspecified". You can't connect to it since it's undefined as a destination.
This is why you're getting a NoRouteToHostException
- the address is simply not routable. You'll get a similar failure if you try to run ping 0.0.0.0
or a similar command.
ConnectionRefused
occurs when the remote machine actually refuses the connection, which is usually a sign that the remote machine doesn't have a listening socket or is behind a firewall.
Upvotes: 7