4

My application needs to ping many IP addresses at once for speed of execution of the code. For example, pinging 300 ip addresses that time out after one second would take 5 minutes, whereas if 20 are run at a time, it only will take about 15 seconds.

I have tried calling windows ping.exe for this, but I have had two separate and similar issues with that. One issue is that on some windows machines, ping will just hang for minutes for seemingly no reason until I kill the thread and it dies. The other issue, we've had ping.exe completely break on machines before, where any ping.exe call lasts forever, so hundreds of ping.exe processes start piling up until the machine crashes, and running ping.exe manually from the command line in that case just leaves another ping process hung forever.

I have tried using a library called icmp4j, but that library only allows one ping at a time to happen on Windows.

I tried this person's code and ended up running into issues on my local network. When pinging a local address that didn't exist (on your subnet), apparently you can get a reply that says that the address is unreachable. On exactly 50% of those replies, I would get a timeout, and on the other 50% I would get 'unpingable.'

Does anyone know a method for running many pings on windows at the same time without using icmp4j or ping.exe?

Community
  • 1
  • 1
Jdban101
  • 367
  • 1
  • 3
  • 21
  • 1
    Possible duplicate of [java code to ping an IP address](http://stackoverflow.com/questions/11506321/java-code-to-ping-an-ip-address) – Tim Mar 30 '16 at 18:42
  • Take a look at: http://stackoverflow.com/questions/3584210/preferred-java-way-to-ping-a-http-url-for-availability – John Kane Mar 30 '16 at 18:46
  • @JohnKane That won't work, because I actually need to do an ICMP ping, not a socket connection. – Jdban101 Mar 30 '16 at 18:54
  • @Tim That post solution ended up being "don't use ICMP ping, use sockets," which doesn't work for me because I need to use ICMP ping. There is a linked post from that thread which is what I am currently trying (and I linked it above in the post), but it seems to be having its own issues. – Jdban101 Mar 30 '16 at 18:56
  • On windows, use the `-n` option (with a small value like `2`) to specify a number of echo requests to send (otherwise it will keep sending echo requests). (note: on some other OS, the option is `-c` for "count"). – Sci Prog Mar 30 '16 at 22:24
  • @SciProg We were using the -n option the whole time, the issues still occured. Ping.exe is not an option. – Jdban101 Mar 30 '16 at 22:35

1 Answers1

1

InetAddress.isReachable() is the bare-bones tool you need.

icmp4j should do the job just fine, as that's just a wrapper around isReachable. Perhaps you can't use the static entry point IcmpPingUtil.executePingRequest(), though a quick review of the code doesn't look terribly worrying. If you go through the code in that method (NativeBridge or JavaNativeBridge, IcmPingRequest and IcmpPingResponse should be enough) then you should be able to build a robust threadsafe class that can do what you need.

Paul Hicks
  • 13,289
  • 5
  • 51
  • 78
  • `InetAddress.isReachable()` when used with windows actually does not ping. It tries a TCP connection to port 7 to see if it gets a reply. http://stackoverflow.com/questions/11587271/isreachable-always-returning-true-regardless-of-what-the-ip-address-is A comment in the `WindowsNativeBridge.java` file makes me think copying from it will have the same issue: _WARNING: this method is synchronized because if multiple threads call IcmpLibrary.IcmpSendEcho (), then the results are corrupted!!! So for now we have no choice other than figure out how to call IcmpSendEcho2, or call ping.exe_ – Jdban101 Mar 30 '16 at 21:47
  • 1
    What worries me their comment is that it DOES give me something to try, but it doesn't necessarily mean that it'll work and its complicated. – Jdban101 Mar 30 '16 at 21:59
  • Do you need the response to be not corrupted? If you just need a ping to ping, and don't need access to the values within the ICMP response, then it might be good enough for your needs. (Alternatively, upgrade to linux) – Paul Hicks Mar 30 '16 at 22:15
  • I can't really upgrade 100+ customer machines to linux :P Also, InetAddress.isReachable is terrible if you want to ping. I just used it on 8.8.8.8 (Google DNS), and it told me it was unreachable. Its also terrible in linux, because for it to work, it REQUIRES root permissions, which is insane. – Jdban101 Mar 30 '16 at 22:24
  • Hmm. Pity java Sockets don't let you select family. You may have to use [IcmpSendEcho2](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366051%28v=vs.85%29.aspx) yourself, and use java to call the native function. If you get it working, you could contribute to icmp4j! – Paul Hicks Mar 30 '16 at 22:28
  • I might end up using their code and attempting to contribute. It seems really weird that they don't actually have a publically downloadable repository. Their sourceforge repository has no commits, the only way to get the files seems to be downloading them manually from a release – Jdban101 Mar 30 '16 at 23:03