Wednesday, April 15, 2009

The Classic Problem of Java Ping

In previous versions of Java (before version 1.5), Java only supported the TCP and UDP protocols. It did not support ICMP protocol. Hence, there was no way of running the ping application from Java other than using native methods (JNI) or the Runtime.exec() to execute shell commands.

In Version 1.5, the InetAddress class had a method called isReachable() which tests whether the address is reachable (also see http://www.rgagnon.com/javadetails/java-0093.html for a good explanation):

try
{
InetAddress addr = InetAddress.getByName(hostName);
pingable = addr.isReachable(timeOut);
}
catch (Exception e)
{
System.out.println("Host " + hostName + " cannot be ping'ed. " +
"Please check to see if this computer is up and running.");
e.printStackTrace();
}

This method sends ICMP “echo request” packets and listens for ICMP “echo response” replies (essentially what the ping network tool does: http://en.wikipedia.org/wiki/Ping). However, as the API says, "firewalls and server configuration may block requests resulting in a unreachable status while some specific ports may be accessible". If this is the case, the method will then establish a TCP connection to Port 7 (which is an echo port on the server that echos whatever to write to that port). THis could also be blocked depending on your firewall settings. Worst comes to worst, you can still use the Runtime.exec() method to execute the ping shell command:

Boolean pingable;
try
{
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("ping.exe " + _hostNameOrIpAddress);

int exitVal = p.waitFor();
System.out.println("Process exitVal " + exitVal);
}
catch (Throwable t)
{
t.getMessage();
pingable = false;
}

This should do the trick. Make sure that if you use a _hostName, there is a mapping of that hostname and IP in your C:\Windows\system32\drivers\hosts file.

No comments:

Post a Comment

Thank you for your comment.