3

I am making a ping program using Java sockets. One bug in my program is that sometimes it will not connect and will just sit there for ever. So I am trying to add a timeout (after twenty seconds) and the ping will fail. But I have no idea how to.

Here is part of my ping program:

boolean result = false;
long before1 = System.nanoTime();
out.println(new byte[64]);
System.out.println("(1) Sent 64 bytes of data to " + address
                    + "...");
try {
    if ((in.readLine()) != null) {
        int size = in.readLine().toString().getBytes().length;
        long after = System.nanoTime();
        long s = ((after - before1) / 1000000L) / 1000;
        System.out.println("(1) Recieved reply from " + address
            + " (" + size + " bytes), time = " + s
                + " seconds...");
        result = true;
    } else if ((in.readLine()) == null) {
        long after = System.nanoTime();
        long s = ((after - before1) / 1000000L) / 1000;
        System.out.println("(1) Failed to recieve reply from "
            + address + ", time = " + s + " seconds...");
            result = false;
    }

} catch (IOException exc) {

    long after = System.nanoTime();
    long s = ((after - before1) / 1000000L) / 1000;
    System.err.println("(1) Failed to recieve reply from "
        + address + ", time = " + s + " seconds...\nReason: "
                        + exc);
    result = false;

}

But I would like to measure time elapsed any where in my code, instead of:

long time = System.nanoTime();

If one part of my code is stuck doing something it will time out after 20 seconds.
Any suggestions on how to measure if twenty seconds has passed at the start of a try/catch block or anywhere else in my code so it doesn't get stuck during the ping?

brasofilo
  • 25,496
  • 15
  • 91
  • 179
0101011
  • 329
  • 2
  • 7
  • 14
  • Threading frameworks have very nice facilities for this. – jn1kk Apr 05 '13 at 20:20
  • 1
    You could execute your ping in a separate thread and use [Thread.join()](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join(long)) to give it some time to complete. – jahroy Apr 05 '13 at 20:21
  • 1
    @jahroy - Ummmm... Could you show me an example? – 0101011 Apr 05 '13 at 20:29
  • I'm a little busy at the moment, but here's [one simple example](http://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html) from the Oracle tutorials. – jahroy Apr 05 '13 at 21:06

3 Answers3

1

As "jsn" and "jahory" said you need to do this with threads. Here's 2 useful links, you can check them ;)

Majid Abarghooei
  • 663
  • 7
  • 21
  • I have seen behavior of a thread and it jams everything up until it's done. Will this do the same? – 0101011 Apr 05 '13 at 20:32
  • 1
    The point of a thread is that your program can continue to execute while the thread works in parallel... So threads should provide solutions in situations where "_everything gets jammed up_". – jahroy Apr 05 '13 at 21:01
1

You can use Future and FutureTask:

   ExecutorService pingExecutor = ... // executor service to run the ping in other thread

   void showPing(final String target) throws InterruptedException {

     Future<String> ping = executor.submit(new Callable<String>() {
         public String call() {
             String pingResult = ... // do your Ping stuff
             return pingResult;
         }});

     System.out.println("Pinging..."); // do other things while searching

     try {
       System.out.println(future.get(20, TimeUnit.SECONDS)); // use future, waits 20 seconds for the task to complete
     } catch (ExecutionException ex) {
     } catch (TimeoutException tex) {
       // Ping timed out
     }
   }
jalopaba
  • 8,039
  • 2
  • 44
  • 57
0

You can find some hints here: How do I call some blocking method with a timeout in Java?

Future interface looks like a good solution to your problem. Remember, however, that depending on what your task is doing, you probably would be not able to really cancel it. Additional info:

Community
  • 1
  • 1