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>