stealthcopter / AndroidNetworkTools

Set of useful android network tools
Apache License 2.0
1.39k stars 282 forks source link

Timeout when host unreachable #49

Closed nikedlab closed 6 years ago

nikedlab commented 6 years ago

Hello! There is how I start pinging

Ping.onAddress(domain).setDelayMillis(500).setTimeOutMillis(500).setTimes(999999999).doPing(pingListener)

It worked fine with specified timings when host is reachable. But when I disable ICMP on my server (for test purposes) the code start working incorrectly. At least TimeOutMillis or DelayMillis reached up to 10 seconds (I don't know how to define which timing is wrong). Is it intentional behavior or may be I missed something?

stealthcopter commented 6 years ago

@nikedlab Any reason you're doing 999999999 pings? That will mean you're waiting a very long time for all the pings to fail.

setDelayMillis - this is delay between sending each ping setTimeOutMillis - this is the timeout for each ping

So with your code you'd be:

  1. Sending a ping
  2. Timeout after 500ms
  3. Wait 500ms
  4. Repeat 999999999 times

This means you'd be waiting about 31 years for all the pings to finish. Can you try running the following code to see if you get the expected output:

Ping.onAddress("microsoft.com").setDelayMillis(500).setTimeOutMillis(500).setTimes(1).doPing(new Ping.PingListener() {
            @Override
            public void onResult(PingResult pingResult) {
                Log.e("TEST", "onResult"+pingResult.toString());
            }

            @Override
            public void onFinished(PingStats pingStats) {
                Log.e("TEST", "onResult"+pingStats.toString());
            }

            @Override
            public void onError(Exception e) {
                Log.e("TEST", "Err", e);
            }
        });

This for me returns the following:

E/TEST: onResultPingResult{ia=microsoft.com/23.100.122.175, isReachable=false, error='failed, exit = 1', timeTaken=0.0, fullString='null', result='null'}
E/TEST: onResultPingStats{ia=microsoft.com/23.100.122.175, noPings=1, packetsLost=1, averageTimeTaken=0.0, minTimeTaken=-1.0, maxTimeTaken=-1.0}
nikedlab commented 6 years ago

Ok, I see. I want to do continuous ping to check network on server. Your approach is to do it in "infinity" loop with setTimes(1)? As I understand setTimes is total amount of ping requests with specified delay and timeout. In my case I want to do every minutes pinging and notice me when server became unreachable and vice versa. That is reason why times is 999999999. Timeout and delay has 500 just for testing

Your example fired callback only once and finished after

stealthcopter commented 6 years ago

Ok, got it. So you have two choices really:

  1. Implement the timing and the loop yourself, this would work well inside an asynctask or similar.
// Inside your own loop / asynctask
PingResult pingResult = Ping.onAddress("yourserver.com").setDelayMillis(500).setTimeOutMillis(500).doPing();
if (ping.isReachable()){
    // Do something
    serverIsReachable();
}
  1. Use the library as before and fire your events from on the onResult method:

// This will call your method when server becomes reachable (just invert the if statement if you want when it becomes unreachable)

// For an infinite loop you can do setTimes(0).

Ping.onAddress("yourserver.com").setDelayMillis(500).setTimeOutMillis(500).setTimes(0).doPing(new Ping.PingListener() {
            @Override
            public void onResult(PingResult pingResult) {
                Log.d("TEST", "onResult"+pingResult.toString());
                if (pingResult.isReachable) {
                    // Call your method when server becomes reachable
                    serverIsReachable();
                }
            }

            @Override
            public void onFinished(PingStats pingStats) {
                // On Finished will not be called if running for infinity unless cancelled
                Log.d("TEST", "onResult"+pingStats.toString());
            }

            @Override
            public void onError(Exception e) {
                Log.e("TEST", "Err", e);
            }
        });
stealthcopter commented 6 years ago

@nikedlab the reason for that code is that the ping command only accepts seconds as whole integers so anything <1 would not work.