3

We have a router and 3 PCs connected.

  1. PC1: 192.168.1.2 (wireless)
  2. PC2: 192.168.1.3 (wireless)
  3. PC3: 192.168.1.6

Default gateway: 192.168.1.1

When PC3 tried to find connected PCs using the code from this forum post, it only returns the IP address of the default gateway (That address is the only reachable address).

I tried increasing the timeout for the isReachable() method. But still it returns only the default gateway address.

I tried doing this to the individual IP addresses.

try {
            InetAddress temp2 = InetAddress.getByAddress(new byte[]{(byte) 192, (byte) 168, (byte) 1, (byte) 2});
            if (temp2.isReachable(1100)) {
                java.lang.System.out.println("IP Address: " + temp2.getHostAddress() + " has connection.");
            }else{
                java.lang.System.out.println("IP Address: " + temp2.getHostAddress() + " has no connection.");
            }
        } catch (Exception ex) {
            java.lang.System.out.println("Error: " + ex.getMessage());
        }  

Yet doing on those PC1 and PC2 IP addresses, I only got a no connection status. (Which means those IPs are not reachable.)

But when I ping them on my windows console those IPs are connected and pinging is successful.

  1. What is the problem with my setup.
  2. How can I resolve this.
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Richeve Bebedor
  • 2,138
  • 4
  • 26
  • 40
  • are you running that on a unix system? – guido Feb 26 '11 at 11:57
  • no i'm running it on windows vista basics os – Richeve Bebedor Feb 26 '11 at 12:40
  • 1
    What is the average ping time for your successful windows console pings? What is the FIRST ping time? If your first ping time is larger than 1100, isReachable() will time out, and return false. – nrobey Feb 26 '11 at 13:57
  • 2
    @Richeve S. Bebedor: what i think is the jvm has no privileges to do a ICMP echo request, and is trying to open a connection to tcp port 7 (or even udp) as a fall back. Can you check with a network sniffer? – guido Feb 27 '11 at 18:38
  • @guido In Windows, if the user can ping from the command line, He should also be able to send ICMP echo request from java. If this indeed fails, TCP echo service isn't open by default on windows, so it's expected to fail (many linux systems also block this today for security reasons). using a sniffer should help you out. – Ophir Yoktan Feb 28 '11 at 07:39

1 Answers1

2

I believe guido is correct with his theory in the comments. See this question. I realize that the linked answer applies to Linux/UNIX hosts, but I just tested your code on a Windows 7 machine and verified that it, also, sends TCP packets to the echo port (7) rather than an ICMP echo request. (I tested this under Java version 1.6.0_21 on a Windows 7 box where ver reported Microsoft Windows [Version 6.1.7600])

A typical Windows machine will likely have Windodws Firewall enabled. Therefore, the following sequence of events is likely:

  1. Your Java program (not being able to send and receive ICMP packets to test for the reachability of the remote Windows host) will attempt to initiate a TCP connection to the remote Windows host, by sending a SYN (synchronize) packet to port 7
  2. The remote Windows host will drop the packet, rather than responding with a RST packet as required by RFC 793 if no service was listening on that port. That is, the remote Windows host should have, per the RFC, have either responded with a TCP:
  • RST: if the port was not listening for connections
  • SYN+ACK: if the port was open and listening for connections
  1. Since your Java program was expecting one of the two things to happen in step (2) but instead got no response at all (since Windows dropped the SYN packet before it ever got to the TCP stack) it falsely assumes the remote Windows host is down.

It's hard to say what the "problem with your setup" is. Maybe nothing. It depends on what you're trying to use this functionality for. You might be going about it in the wrong way. You should realize that ping is not always a 100% accurate way to test if a host is online. In your case it might be more accurate to check the ARP table after trying to ping the host, if you're only interested in hosts on your local network.

Possible workarounds:

  • Try turning off the Windows firewall temporarily on one of the other machines and see if your code works.
  • Write some code that executes a separate process, for example runs the ping command line utility to test reachability.
Community
  • 1
  • 1
mpontillo
  • 13,559
  • 7
  • 62
  • 90
  • Not quite. Since the connection was *not* flat-out refused with a packet saying so, isReachable() assumes the host is down. If it got an RST it would consider the host to be *up.* – user207421 Feb 28 '11 at 02:25
  • @EJP, I think that's what I said. ;-) Feel free to edit my answer if you feel it isn't clear enough. – mpontillo Feb 28 '11 at 04:17
  • @EJP, thanks for trying. ;-) You motivated me to completely rewrite that section of the answer. Is it clearer now? – mpontillo Feb 28 '11 at 08:46