How to Do a True Java Ping from Windows

How to do a true Java ping from Windows?

isReachable() will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.

Thus your problem is probably a configuration issue of not enough permissions to do this on the client machine or a port 7 issue on the server if your client doesn't have permission to do the ICMP ECHO REQUEST. Probably both in your case, you need to resolve one side or the other to get this to work.

I tested the following on OSX and Linux clients and it works when testing for reachablity of other OSX, Linux and Windows Server machines. I don't have a Windows machine to run this as a client.

import java.io.IOException;
import java.net.InetAddress;

public class IsReachable
{
public static void main(final String[] args) throws IOException
{
final InetAddress host = InetAddress.getByName(args[0]);
System.out.println("host.isReachable(1000) = " + host.isReachable(1000));
}
}

from what I read here. It is apparently a Windows limitation and ICMP PING isn't supported on Windows as a system call previous to Windows 2000, so it defaults to try and connect to Port 7 and that is blocked on the machine you are trying to "reach". Java doesn't support the new native system call yet. The permissions thing is for Unix based system as they require root to send ICMP packets.

If you want to roll your own Windows native JNI ICMP PING for Windows 2000 and newer there is the IcmpSendEcho Function.

How to ping an IP address

You can not simply ping in Java as it relies on ICMP, which is sadly not supported in Java

http://mindprod.com/jgloss/ping.html

Use sockets instead

Hope it helps

How to ping and keep statistics in Java

This is not a good one to use for most external ips.
Instead following can be used

boolean reachable = (java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.lk").waitFor()==0);

How to perform a ping-test programmatically on Windows?

If on Windows you need to check programmatically if an host is reachable, I suggest using _popen() instead of system().

In fact with pipes you can execute a command like with system(), but in addition its output is redirected to a stream. After that you can access the stream exactly how you'd do with a file, reading the output and parsing whatever you need.

At this link you can find Microsoft official documentation for _popen(). You will be easily able to find all related functions (such as _pclose()).

In the following demonstrative program a ping command is sent (asking for only two echoes to Google DNS server in order to save time). Then the obtained FILE *, opened in textual read mode, is used to access the stream with a normal loop of fread() calls:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define BUFFER_SIZE 1024

char buffer[BUFFER_SIZE] = { 0 };

int main( void )
{
FILE * pipe = _popen( "ping 8.8.8.8 -n 2", "rt" );
if( pipe != NULL )
{
int rd = 0, ret;

while( ( ret = fread( buffer+rd, 1, BUFFER_SIZE - rd, pipe ) ) > 0 )
{
rd += ret;
}

if( strstr( buffer, "TTL=" ) != NULL )
{
printf( "\nThe host is reachable!\n" );
}
else
{
printf( "\nThe host is NOT reachable!\n" );
}

//printf( "%d bytes read\n\n%s\n", rd, buffer );

_pclose( pipe );
}
else
{
printf( "Error in pipe opening!\n" );
}
return 0;
}

Some further explanation

  • In this example only simple host reachability is verified. An host is considered reachable if at least an echo comes back. It is a starting point for any other information you might need to parse.
  • I've done it by checking the presence of TTL= substring, that I'm sure will be present in every language in case of successful ping (the output may be printed in different languages according to PC settings).
  • Tailor your buffer size to the length you expect is required to find the needed substring. In my example 1024 bytes were far enough for the expected response length.
  • You can find, commented, the print of the whole buffer. You can use that string to check everything you need (for example average ping time).
  • In order to read from the stream, feel free to use your favourite function. Another popular alternative would be fgets(), that would be great to read and parse one line at a time, and would also require a smaller reading buffer.


Similar in Linux

Though the question is about Windows, I have to say that the implementation on Linux would be very similar, based on popen(), pclose() and so on.

You can find the description of the mentioned functions in the manual page.

How to test if a remote system is reachable

InetAddress.getByName(ip).isReachable(timeout);


Related Topics



Leave a reply



Submit