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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With