Ping Class java

  • Thread starter Marc van den Bogaard
  • Start date
M

Marc van den Bogaard

Hi all!

Does anyone know a Ping Class in Java
to do a simple "ping" on a server and reading the response?

Didn't find anything usefull up to now.


Thank you in advance!
 
S

Skip

Marc van den Bogaard said:
Hi all!

Does anyone know a Ping Class in Java
to do a simple "ping" on a server and reading the response?

Didn't find anything usefull up to now.

In the Sun Runtime there are no APIs that expose this behaviour.
 
M

Marc van den Bogaard

Skip said:
In the Sun Runtime there are no APIs that expose this behaviour.

In the meantime I found out, that Java doesn't support
Raw Sockets which are necessary to do such a ICMP ECHO (Ping).

But you can use Native C Code.
Calling the native code using the JNI interface.
The finishing touch is to wrap the JNI call in an RMI class.

Thats the theory...
 
C

Camel

Try the following code. Hope it helps.
--------------------------------------------------

import java.net.*;
import java.io.*;
import java.util.*;

public class pingTest {

public static void main(String[] args) {

String ip = args[0];
String pingResult = "";

String pingCmd = "ping " + ip;

try {
Runtime r = Runtime.getRuntime();
Process p = r.exec(pingCmd);

BufferedReader in = new BufferedReader(new
InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
pingResult += inputLine;
}
in.close();

}//try
catch (IOException e) {
System.out.println(e);
}

}

}
 
R

Roedy Green

Does anyone know a Ping Class in Java
to do a simple "ping" on a server and reading the response?

Ping is a very low level protocol not supported by Java. You can get
the same effect probing one of the higher level protocols supported
like HTTP, FTP, SMTP, NTP, NNTP...

More and more servers are ignoring ping probes.
 
S

steve

Hi all!

Does anyone know a Ping Class in Java
to do a simple "ping" on a server and reading the response?

Didn't find anything usefull up to now.


Thank you in advance!

here ya go.

steve



//this class is for testing the conectivity to a database
//actually it times the connection setup time
//in theory this can be used to find the closest database to the client
location.
//date may-09-2004
package Services;

import java.io.*;

import java.net.*;


public class Pinger {
// byte[] addr1 = new byte[]{(byte)192,(byte)168,(byte)2,(byte)5};

public static long testDBConn(byte[] addr1, int port, int timeoutMs) {
//pass in a byte array with the ipv4 address, the port & the max time
out required
long start = -1; //default check value
long end = -1; //default check value
long total = -1; // default for bad connection

//make an unbound socket
Socket theSock = new Socket();

try {
InetAddress addr = InetAddress.getByAddress(addr1);

SocketAddress sockaddr = new InetSocketAddress(addr, port);

// Create the socket with a timeout
//when a timeout occurs, we will get timout exp.
//also time our connection this gets very close to the real time
start = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end = System.currentTimeMillis();
} catch (UnknownHostException e) {
start = -1;
end = -1;
} catch (SocketTimeoutException e) {
start = -1;
end = -1;
} catch (IOException e) {
start = -1;
end = -1;
} finally {
if (theSock != null) {
try {
theSock.close();
} catch (IOException e) {
}
}

if ((start != -1) && (end != -1)) {
total = end - start;
}
}

return total; //returns -1 if timeout
}
}
 
S

steve

Hi all!

Does anyone know a Ping Class in Java
to do a simple "ping" on a server and reading the response?

Didn't find anything usefull up to now.


Thank you in advance!

whoops.

heres a test case

/*
//This is a test class
public static void main(String[] args) {

// byte[] addr1 = new
byte[]{(byte)192,(byte)168,(byte)2,(byte)5};
int port = 1521;
int timeoutMs = 2000; // 2 seconds
long value = testDBConn(addr1, port, timeoutMs);
System.out.println(value);
}
*/


basically , you don't need to implement a "ping" , by using the java classes
correctly, to get a connection reply , you have to make a connection by
opening a socket.

logically if you can open a socket , the server must be connected.
you do not actually have to send any data , just look for a socket
connection.


steve
 
G

Guenter Dannhaeuser

//this class is for testing the conectivity to a database
//actually it times the connection setup time
//in theory this can be used to find the closest database to the client
location. [...]
// Create the socket with a timeout
//when a timeout occurs, we will get timout exp.
//also time our connection this gets very close to the real time
start = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end = System.currentTimeMillis();
} catch (UnknownHostException e) {
start = -1;
end = -1;
} catch (SocketTimeoutException e) {
start = -1;
end = -1;
[...]

Hi,

I´ve tried this, but apparently the timeout value is neglected.
Testing a connection to a host using a timeoutMS of 300 resulted in
values (end-start) > 4000 in that case. No SocketTemoutException
raised. Tested with JDK1.5.0_03 and _05. Any ideas?

Thanks,
guenter <gd--acm-org>
 
R

Roedy Green

I´ve tried this, but apparently the timeout value is neglected.
There was another post recently complaining timeouts were being
ignored.

Maybe that number is really just a suggested MINIMUM timeout and the
actual can be much longer.

Perhaps the problem is in the OS.

Is anyone aware of experiments on this?
 
S

steve

//this class is for testing the conectivity to a database
//actually it times the connection setup time
//in theory this can be used to find the closest database to the client
location. [...]
// Create the socket with a timeout
//when a timeout occurs, we will get timout exp.
//also time our connection this gets very close to the real time
start = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end = System.currentTimeMillis();
} catch (UnknownHostException e) {
start = -1;
end = -1;
} catch (SocketTimeoutException e) {
start = -1;
end = -1;
[...]

Hi,

I´ve tried this, but apparently the timeout value is neglected.
Testing a connection to a host using a timeoutMS of 300 resulted in
values (end-start) > 4000 in that case. No SocketTemoutException
raised. Tested with JDK1.5.0_03 and _05. Any ideas?

Thanks,
guenter <gd--acm-org>

how odd!!
it was cut directly from a working file.

and it is working perfectly on macs and on windows se, but then again we are
on 1.4.2.

I know it works , because i use it to decide between 2 different databases,
for clients internally and externally to the network.


it takes 5 reading , for 192.168.2.9, XXX.XXX.XXX.XXX, YYY.YYY.YYY.YYY,
then averages out the connection times.
XXX.XXX.XXX.XXX, YYY.YYY.YYY.YYY, are in different parts of the world.

if you are connected internally it connects to : 192.168.2.9
if you are external it makes a connection to either : XXX.XXX.XXX.XXX,
YYY.YYY.YYY.YYY depending on the lowest latency.

it checks 192.168.2.9, first so if it was not timing out in less than 4
seconds , the client would get stuck , for 20 seconds ( 5 readings of 4
seconds).


I just tested it for a local database i got 11ms
for no database i got -1

that was using
//This is a test class
public static void main(String[] args) {


// byte[] addr1 = new
byte[]{(byte)192,(byte)168,(byte)2,(byte)5};
int port = 1521;
int timeoutMs = 2000; // 2 seconds
long value = testDBConn(addr1, port, timeoutMs);
System.out.println(value);
}

then i tested a database that i know drops some packets:, all this was in
less than 3 seconds.

Debugger connected to local process.
Deadlock detection is not supported by the debuggee virtual machine.
31
13
14
-1
15
15
15
15
15
15
15
14
15
-1
16
-1
15
15
16
15
16
-1
16
15
15
16
16
15
15
16
15
16
15
15
16
16
15
15
16
16
16
15
17
65
17
67
33
15
14
20
15
15
15
15
15
16
15
16
14
16
15
16
16
15
15
17
16
15
15
15
16
15
15
15
17
18
16
17
64
16
15
15
16
15
15
16
31
16
16
15
16
15
16
16
15
16
15
15
15
16
15
15
16
15
16
16
15
15
-1
27
17
15
15
16
15
16
15
16
15
14
16
16
16
58
15
19
16
16
16
17
16
17
Debuggee process paused.
 
G

Guenter Dannhaeuser

Ok, some more testing done, I now think the problem is not the timeout
being ignored, but the time for executing the connect: doing something
like

[...]
Socket theSock = new Socket();
start0 = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end0 = System.currentTimeMillis();

theSock = new Socket();
start1 = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end1 = System.currentTimeMillis();
[...]

sometimes returns big values (>4000ms) for (end0 - start0) and usually
values in the expected range for (end1 - start1). Is this a problem of
JIT-Compiling?

However, looking at
http://java.sun.com/j2se/1.5.0/docs/guide/nio/example/Ping.java
I´ve managed to get a solution that´s working for me atm, based on a
thread observing finishConnect() on a SocketChannel.
Please excuse any bad coding style (it´s my first week on java ;) -
remarks very welcome.

-- 8< -------------------------------------------------------------
package myping;

import java.io.*;
import java.net.*;
import java.nio.channels.*;


public class Ping {

private static int timeout; // Timeout in ms for pinging
private static Target t;
private static SocketChannel sc;

// Representation of a ping target
private static class Target {

public InetSocketAddress address;
public SocketChannel channel;
public long connectStart;
public long connectFinish = 0;
public Exception failure = null;

public Target(String host, int port) throws IOException {
address = new
InetSocketAddress(InetAddress.getByName(host), port);
}

public long getPing() throws IOException, InterruptedException
{
if (connectFinish != 0)
return connectFinish - connectStart;
else if (failure != null)
if (failure instanceof IOException)
throw (IOException) failure;
else if (failure instanceof InterruptedException)
throw (InterruptedException) failure;
else
return -2; //should not happen
else
return -1; //Timed out
}
}

// Thread for connecting to target
private static class connector extends Thread {

private volatile boolean shutdown = false;

public connector() {
setName("connector");
}
public void shutdown() {
shutdown = true;
}
public void run() {
for (;;) {
if (shutdown) {
return;
}
// Attempt to complete the connection sequence
try {
if (sc.finishConnect()) {
t.connectFinish = System.currentTimeMillis();
sc.close();
return;
}
} catch (IOException x) {
try {
sc.close();
} catch (IOException xx) {
t.failure = xx;
}
t.failure = x;
}
}
}
}

public static long ping(String host, int port, int timeout) throws
InterruptedException, IOException {

Ping.t = new Target(host, port);
Ping.timeout = timeout;

// Initiate a connection sequence to the given target
Ping.sc = null;
// Open the channel, set it to non-blocking, initiate connect
sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(t.address);
// Record the time we started
t.connectStart = System.currentTimeMillis();
t.channel = sc;

connector conn = new connector();
conn.start();
conn.join(timeout);
conn.shutdown();

sc.close();
return t.getPing();
}

public static void main(String[] args) throws
InterruptedException, IOException {

System.out.println(ping("123.123.123.123", 7, 500)); //host,
port, timeout in ms
}

}
-- 8< -------------------------------------------------------------

cheers,
guenter. <gd--acm-org>
 
R

Roedy Green

start1 = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end1 = System.currentTimeMillis();

You never showed us your code for displaying end1-start1. You may
have muddled the values before displaying them.
 
E

E.J. Pitt

Alan said:
Just to be clear, that doesn't implement an ICMP-based ping (echo
request and response). Instead, it connects to the daytime port (port
13) at the specified host. A declining number of hosts actually support
that service anymore.

Err, 'A typical implementation 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.'
 
G

Guenter Dannhaeuser

You never showed us your code for displaying end1-start1. You may
have muddled the values before displaying them.

Ok, I´ve surrounded the measurement in steve´s class with a for-loop
and output it directly:

-- 8< ----------------------------------------------------------------
import java.io.*;
import java.net.*;

public class Pinger {
// byte[] addr1 = new
byte[]{(byte)192,(byte)168,(byte)2,(byte)5};

public static long testConn(byte[] addr1, int port, int timeoutMs)
{
//pass in a byte array with the ipv4 address, the port & the
max time out required
long start = -1; //default check value
long end = -1; //default check value
long total = -1; // default for bad connection


//make an unbound socket
Socket theSock = null;
try {
InetAddress addr = InetAddress.getByAddress(addr1);
SocketAddress sockaddr = new InetSocketAddress(addr,
port);

// Create the socket with a timeout
//when a timeout occurs, we will get timout exp.
//also time our connection this gets very close to the
real time
for (int i = 0; i < 10; i++) {
theSock = new Socket();
start = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end = System.currentTimeMillis();
System.out.println(end - start);
}
} catch (UnknownHostException e) {
start = -1;
end = -1;
} catch (SocketTimeoutException e) {
start = -1;
end = -1;
} catch (IOException e) {
start = -1;
end = -1;
} finally {
if (theSock != null) {
try {
theSock.close();
} catch (IOException e) {
}
}

if ((start != -1) && (end != -1)) {
total = end - start;
}
}

return total; //returns -1 if timeout
}

public static void main(String[] args) {
byte[] addr = new
byte[]{(byte)123,(byte)123,(byte)123,(byte)123};
int port = 123;
int timeout = 500;

for (int i = 0; i < 2; i++) {
System.out.println(Pinger.testConn(addr, port, timeout));
}
}
}
-- 8< ----------------------------------------------------------------

Output for this always is something like
-- 8< ----------------------------------------------------------------
4802
282
281
282
266
282
281
282
281
282
282
4771
282
281
282
297
282
297
266
281
282
282
-- 8< ----------------------------------------------------------------

greets,
guenter. <gd--acm-org>
 
S

steve

You never showed us your code for displaying end1-start1. You may
have muddled the values before displaying them.

Ok, I´ve surrounded the measurement in steve´s class with a for-loop
and output it directly:

-- 8< ----------------------------------------------------------------
import java.io.*;
import java.net.*;

public class Pinger {
// byte[] addr1 = new
byte[]{(byte)192,(byte)168,(byte)2,(byte)5};

public static long testConn(byte[] addr1, int port, int timeoutMs)
{
//pass in a byte array with the ipv4 address, the port & the
max time out required
long start = -1; //default check value
long end = -1; //default check value
long total = -1; // default for bad connection


//make an unbound socket
Socket theSock = null;
try {
InetAddress addr = InetAddress.getByAddress(addr1);
SocketAddress sockaddr = new InetSocketAddress(addr,
port);

// Create the socket with a timeout
//when a timeout occurs, we will get timout exp.
//also time our connection this gets very close to the
real time
for (int i = 0; i < 10; i++) {
theSock = new Socket();
start = System.currentTimeMillis();
theSock.connect(sockaddr, timeoutMs);
end = System.currentTimeMillis();
System.out.println(end - start);
}
} catch (UnknownHostException e) {
start = -1;
end = -1;
} catch (SocketTimeoutException e) {
start = -1;
end = -1;
} catch (IOException e) {
start = -1;
end = -1;
} finally {
if (theSock != null) {
try {
theSock.close();
} catch (IOException e) {
}
}

if ((start != -1) && (end != -1)) {
total = end - start;
}
}

return total; //returns -1 if timeout
}

public static void main(String[] args) {
byte[] addr = new
byte[]{(byte)123,(byte)123,(byte)123,(byte)123};
int port = 123;
int timeout = 500;

for (int i = 0; i < 2; i++) {
System.out.println(Pinger.testConn(addr, port, timeout));
}
}
}
-- 8< ----------------------------------------------------------------

Output for this always is something like
-- 8< ----------------------------------------------------------------
4802
282
281
282
266
282
281
282
281
282
282
4771
282
281
282
297
282
297
266
281
282
282
-- 8< ----------------------------------------------------------------

greets,
guenter. <gd--acm-org>

how odd!!.
I'm normally very careful before releasing code, to ensure it is good.

I currently have this running over several hundred clients, with the results
back-ended to an oracle database, and have not seen this.

Perhaps it is actually correct-!!, and you seeing , either something in the
jvm or you are seeing some real latency in the network for some reason.

I have just run it over 7 different hosts in our network, from both inside
and outside the net. and i cannot duplicate your problem.
the only thing i see is the -1.
but to get a result of 4771, 4802 ,would indicate the timer is not firing
in 500ms, which would indicate a possible jvm bug,(or a service tie up,
which would still be a bug)
perhaps you need to pass the code to sun along with details of your setup.

the code differs in that it is actually a service finder, as opposed to a
real ping, in was using it for looking for services.
and originally i also passed in the port numbers.

try adding a for next delay of about 1 second , between calls, it might be a
function of your firewall. trying to stop a DOS attack ( currently the code
runs as fast as it can open a port, which with a single ip address looks very
much like a DOS)

maybe we can get others in the group to run the code to see what their
results are?

Anyway This is from a client outside our company to our server, i''ll not
bore you with 7 outputs

actual ping from my system.

64 bytes from 59.37.49.52: icmp_seq=0 ttl=58 time=11.966 ms
64 bytes from 59.37.49.52: icmp_seq=1 ttl=58 time=11.721 ms
64 bytes from 59.37.49.52: icmp_seq=2 ttl=58 time=11.959 ms
64 bytes from 59.37.49.52: icmp_seq=3 ttl=58 time=11.968 ms
64 bytes from 59.37.49.52: icmp_seq=4 ttl=58 time=23.224 ms
64 bytes from 59.37.49.52: icmp_seq=5 ttl=58 time=15.842 ms
64 bytes from 59.37.49.52: icmp_seq=6 ttl=58 time=22.223 ms
64 bytes from 59.37.49.52: icmp_seq=7 ttl=58 time=44.964 ms
64 bytes from 59.37.49.52: icmp_seq=8 ttl=58 time=11.691 ms
64 bytes from 59.37.49.52: icmp_seq=9 ttl=58 time=11.458 ms
64 bytes from 59.37.49.52: icmp_seq=10 ttl=58 time=12.414 ms
64 bytes from 59.37.49.52: icmp_seq=11 ttl=58 time=11.668 ms
64 bytes from 59.37.49.52: icmp_seq=12 ttl=58 time=11.675 ms
64 bytes from 59.37.49.52: icmp_seq=13 ttl=58 time=18.756 ms
64 bytes from 59.37.49.52: icmp_seq=14 ttl=58 time=13.318 ms
64 bytes from 59.37.49.52: icmp_seq=15 ttl=58 time=12.168 ms
64 bytes from 59.37.49.52: icmp_seq=16 ttl=58 time=11.939 ms
64 bytes from 59.37.49.52: icmp_seq=17 ttl=58 time=25.141 ms
64 bytes from 59.37.49.52: icmp_seq=18 ttl=58 time=12.409 ms
64 bytes from 59.37.49.52: icmp_seq=19 ttl=58 time=11.442 ms
64 bytes from 59.37.49.52: icmp_seq=20 ttl=58 time=23.186 ms
64 bytes from 59.37.49.52: icmp_seq=21 ttl=58 time=11.643 ms
64 bytes from 59.37.49.52: icmp_seq=22 ttl=58 time=12.131 ms
64 bytes from 59.37.49.52: icmp_seq=23 ttl=58 time=21.207 ms
64 bytes from 59.37.49.52: icmp_seq=24 ttl=58 time=22.406 ms
64 bytes from 59.37.49.52: icmp_seq=25 ttl=58 time=15.277 ms
64 bytes from 59.37.49.52: icmp_seq=26 ttl=58 time=20.682 ms

from the java thingy jvm 1.4.2_09

12
40
15
15
16
15
19
16
59
27
15
16
67
15
16
16
15
63
26
17
15
18
59
15
16
15
16
34
15
24
20
16
15
61
15
15
15
16
76
27
17
17
58
15
16
15
15
67
20
16
16
64
15
16
15
15
37
-1
62
17
16
15
16
-1
15
15
60
20
17
16
-1
20
16
68
62
16
18
16
18
16
15
16
33
16
15
15
16
40
53
15
15
15
15
58
15
16
-1
16
16
-1
16
15
16
14
16
47
17
16
15
28
15
64
68
33
16
16
30
16
15
68
21
24
28
17
17
15
26
18
66
16
16
22
17
61
19
16
16
44
34
15
25
16
47
17
15
15
16
16
63
16
15
22
16
58
16
16
15
16
64
-1
23
15
16
16
17
19
67
58
17
15
15
15
16
15
16
16
76
58
16
55
13
17
65
73
19
15
15
15
17
15
15
16
-1
16
44
34
15
15
14
15
70
13
18
48
14
16
16
16
16
41
16
23
26
21
66
15
15
16
38
-1
15
59
15
15
15
15
68
14
15
16
15
60
15
16
14
17
72
18
15
18
66
15
15
16
16
68
18
15
15
15
37
 
A

Alan Krueger

E.J. Pitt said:
Err, 'A typical implementation 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.'

You should probably cite what you're quoting. In any event, as I
stated, the sample at the URL above does not use TCP port 7, it uses TCP
port 13, the 'daytime' service which seems rarely supported anymore.

A better implementation using the 'echo' service might use UDP instead,
since it doesn't require a connection to be established.
 
E

E.J. Pitt

Alan said:
You should probably cite what you're quoting.

Sorry, I'm quoting the Javadoc for InetAddress.isReachable(), which is
what I thought we were talking about. It wasn't, but it should have been ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top