How to quickly check if URL server is available
Asked Answered
M

8

29

I have a URL in the form

http://www.mywebsite.com/util/conv?a=1&from=%s&to=%s

And want to check if it is available.

The links redirect me on a bad request page if I try to open these with a browser, however via code I can get the data that I need.

Using a try-catch block on a HTTP request procedure is pretty slow, so I'm wondering how I could ping a similar address to check if its server is active.


I have tried

boolean reachable = InetAddress.getByName(myLink).isReachable(6000);

But returns always false.

I have also tried

public static boolean exists(String URLName) {

    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
        con.setConnectTimeout(1000);
        con.setReadTimeout(1000);
        con.setRequestMethod("HEAD");
        return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

That returns the correct value at the end of the process, bit is too slow if server is not available.

EDIT

I have understood what is the cause of slowness

a) if server returns some data but interrupts the request before complete the request the timeout is ignored and stuck until returns an Exception that lead the execution to reach the catch block, this is the cause of the slowness of this method, and still I haven't found a valid solution to avoid this.

b) If I start the android device and open the App without connection, the false value is returned correctly, if the app is opened with internet connection active and the device lost its internet connection happens the same thing of the case A (also if I try to terminate and restart the App... I don't know why, I suppose that something remains cached)

All this seems related to the fact Java URLConnection doesn't provide no fail-safe timeout on reads. Looking at the sample at this link I have seen that uses a thread to interrupt the connection in some way but if I add simply the line new Thread(new InterruptThread(Thread.currentThread(), con)).start(); like in the sample nothing changes.

Modular answered 12/9, 2014 at 9:55 Comment(6)
try using getResponseMessage() or getResponseCode()Glimp
Bad Request means your URL is invalid, but not that the server is not availableLemos
@mtetno Could you give me more detail a use has answered something similar but seems as slow as waiting for exception of related try catch blockModular
Lets dicuss in stackoverflow chatGlimp
@mtetno I was offline when you have written the comment, If we connect at different time maybe start a chat would be not easy, why you don't give an answer? I will be glad to accept and upvote if solve my problem, and in addition if someone has the same issue could find a useful help. ThanksModular
referGothurd
S
30
static public boolean isServerReachable(Context context) {
    ConnectivityManager connMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = connMan.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnected()) {
        try {
            URL urlServer = new URL("your server url");
            HttpURLConnection urlConn = (HttpURLConnection) urlServer.openConnection();
            urlConn.setConnectTimeout(3000); //<- 3Seconds Timeout 
            urlConn.connect();
            if (urlConn.getResponseCode() == 200) {
                return true;
            } else {
                return false;
            }
        } catch (MalformedURLException e1) {
            return false;
        } catch (IOException e) {
            return false;
        }
    }
    return false;
}

or by using runtime:

Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("ping www.serverURL.com"); //<- Try ping -c 1 www.serverURL.com
int mPingResult = proc .waitFor();
if(mPingResult == 0){
    return true;
}else{
    return false;
}

You can try isReachable() but there is a bug filed for it and this comment says that isReachable() requires root permission:

try {
    InetAddress.getByName("your server url").isReachable(2000); //Replace with your name
    return true;
} catch (Exception e)
{
    return false;
}
Shend answered 17/9, 2014 at 10:4 Comment(6)
the first sample has the same problem of the code that I have posted(works but is slow when server doesn't give response), the second sample returns always falseModular
i have edited my answer, also try ping -c 1 www.serverURL.comShend
I have added -1 c after ping, but return always false despite the first method on the same link return correctly trueModular
well you can refer this SO Post, which used java.net.SocketShend
first sample => java.net.MalformedURLException: Protocol not found: www.google.comMckibben
I have an error message : android.os.NetworkOnMainThreadExceptionTillie
M
7
public static boolean exists(String URLName) {

        try {
            HttpURLConnection.setFollowRedirects(false);
            // note : you may also need
            // HttpURLConnection.setInstanceFollowRedirects(false)
            HttpURLConnection con = (HttpURLConnection) new URL(URLName)
            .openConnection();
            con.setRequestMethod("HEAD");
            return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
Moral answered 12/9, 2014 at 12:51 Comment(1)
This code works but is as slow as waiting for the Exception of try catch blockModular
C
1

have you tried using raw sockets?

It should run faster as it's on a lower layer

static boolean exists(String serverUrl)  {

    final Socket socket;

    try {
        URL url = new URL(serverUrl);
        socket = new Socket(url.getHost(), url.getPort());
    } catch (IOException e) {
        return false;
    }

    try {
        socket.close();
    } catch (IOException e) {
        // will never happen, it's thread-safe
    }

    return true;
}
Centriole answered 17/9, 2014 at 6:44 Comment(1)
with this code app crashes and get port out of range exceptionModular
B
0

As mentioned by 'eridal', that should be faster, open the socket; however, it only tells you that a server is listening on the host and port but to be sure, you need to write HTTP or alternately a bad request (junk), you should get HTTP/1.1 400 Bad Request. By reading the first line returned, if it contains HTTP, then you are sure that the server is a HTTP server. This way you are sure that the server is available as well as a HTTP server.

This is in extension to the above answer by eridal.

Bedraggle answered 17/9, 2014 at 10:18 Comment(0)
I
0

I had similar problem last month and someone helped me out with an optional example. I'd like to suggest you the same

public boolean isServerReachable()
    // To check if server is reachable
    {
        try {
            InetAddress.getByName("google.com").isReachable(3000); //Replace with your name
            return true;
        } catch (Exception e) {
            return false;
        }
    }

if return true than your url server is available else is not available currently.

Isolde answered 19/9, 2014 at 5:55 Comment(5)
or you may check #25542440Isolde
as I have said in my question this code rteturns always false with my linkModular
Your link takes you to the link "website.1and1.com/#top" so try only with website.1and1.com . It returns trueIsolde
android.os.NetworkOnMainThreadException message error. It doesn't workTillie
so it returned false, which means server not recheable.Isolde
D
0

Below code waits until webpage is available:

public void waitForWebavailability() throws Exception {
        boolean success = false;
        long waitTime = 0;
        while (!success) {
            try {
                waitTest(30000);
                waitTime += 30000;
                if (waitTime > 600000) {

                    System.out.println("Web page is not available");
                }
                webDriver.get("http://www.google.com");
                if (webDriver.getTitle().toLowerCase().contains("sometitle")) {
                    success = true;
                }
            } catch (Exception e) {
                success = false;
            }

        }

    }

// Code related to waittest

public void waitTest(long millis) throws Exception {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            throw new Exception(e);
        }
    }
Dubose answered 7/1, 2016 at 8:17 Comment(0)
C
0

here the writer suggests this:

public boolean isOnline() {
    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int     exitValue = ipProcess.waitFor();
        return (exitValue == 0);
    } catch (IOException | InterruptedException e) { e.printStackTrace(); }
    return false;
}

Couldn’t I just ping my own page, which I want to request anyways?Sure! You could even check both, if you want to differentiate between “internet connection available” and your own servers beeing reachable

read the link. its seems very good

EDIT: in my exp of using it, it's not as fast as this method:

public boolean isOnline() {
    NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

they are a bit different but in the functionality for just checking the connection to internet the first method may become slow due to the connection variables.

Calkins answered 29/8, 2017 at 12:41 Comment(0)
L
-1
if (android.os.Build.VERSION.SDK_INT > 9) {
                            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                                    .permitAll().build();

                            StrictMode.setThreadPolicy(policy);
                        }
                        try {
                            URL diachi = new URL("http://example.com");
                            HttpURLConnection huc = (HttpURLConnection) diachi.openConnection();
                            huc.setRequestMethod("HEAD");
                            int responseCode = huc.getResponseCode();

                            if (responseCode != 404) {
                                //URL Exist

                            } else {
                                //URL not Exist
                            }
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
Louise answered 22/9, 2014 at 6:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.