13 July 2005

Simple Ping with Java NIO

If you're learning Java NIO and reading the Sun's example, it's looks complete but so horrific. Sometimes that's not exactly what you want to do. Pinging a remote is one basic thing Java doesn't fundamentally offer because it doesn't support ICMP protocol, But I was intrigued about Java 5.0's InetAddress.isReachable(), according to its javadoc it uses the OS's ICMP implementation. But that's Java 5.0 and many of us maybe moving to that version perhaps by next year or not at all. Believe me, even some "most high-tech" U.S. companies today still uses Java 1.1

Going back to our simple Ping program, we'll be using Java NIO's DatagramChannel to send and receive packets to imitate a ping action. But before we go to the code, here's a brief description of how our Java NIO Ping will work. First it will open a DatagramChannel, connects to the remote host using an InetSocketAddress with echo port 7, sends packets using ByteBuffer, receive packets that contains the sent value in a ByteBuffer indicating a successful ping. Otherwise the remote host is unreachable or has timed out.

Listing 1: Ping.java



import java.nio.*;
import java.net.*;

public class Ping{

public void pingMe(){

try{
ByteBuffer send = ByteBuffer.wrap("Hello".getBytes());
ByteBuffer receive = ByteBuffer.allocate(
"Hello".getBytes().length);
//use echo port 7
InetSocketAddress socketAddress =
new InetSocketAddress("192.168.1.2", 7);
DatagramChannel dgChannel = DatagramChannel.open();
//we have the channel non-blocking.
dgChannel.configureBlocking(false);
dgChannel.connect(socketAddress);
dgChannel.send(send, socketAddress);
/* it's non-blocking so we need some amount of delay
* to get the response
*/
Thread.sleep(100);
dgChannel.receive(receive);
String response = new String(receive.array());
if (response.equals("Hello")){
System.out.println("Ping is alive");
}else{
System.out.println("No response");
}

} catch (IOException e){
e.printStackTrace();
} catch(InterruptedException e){
e.printStackTrace();
}


}
}


Sometimes this is not an ideal solution, but for quick and dirty checking of networks programmatically, this code has been very handy with me ever since NIO came out.

5 comments:

Anonymous said...

Jared,

this will only work if the "echo service" is on..at the moment, no server will open this (*nix) and is always off by default.

Warren

Anonymous said...

that is why it's called quick and dirty ;)

Anonymous said...

I've tested this sample and by default, Fedora Core has this service running by default.

Jared said...

Hahaha, you're right "echo service" is not always on.

For some serious Java ping sample Daniel Saverese' RockSaw project is the most ideal.

kwiedera said...

Hi,

"But I was intrigued about Java 5.0's InetAddress.isReachable(), according to its javadoc it uses the OS's ICMP implementation."

which, effectively, means ICMP in Java is possible and used by Sun, but not supported by a Sun Java API. Thus
a real ping cannot be handcrafted with
just the JRE. )-: