web-dev-qa-db-ja.com

URLサーバーが利用可能かどうかをすばやく確認する方法

フォームにURLがあります

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

そして、それが利用可能かどうかを確認したい。

ブラウザでこれらを開こうとすると、リンクは悪いリクエストページにリダイレクトされますが、コードを介して必要なデータを取得できます。

HTTPリクエストプロシージャでtry-catchブロックを使用するのはかなり遅いので、サーバーがアクティブであるかどうかを確認するために、同様のアドレスにpingを実行する方法を疑問に思っています。


私が試してみました

_boolean reachable = InetAddress.getByName(myLink).isReachable(6000);
_

ただし、常にfalseを返します。

私も試しました

_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;
    }
}
_

プロセスの最後に正しい値を返します。サーバーが利用できない場合、ビットは遅すぎます。

[〜#〜] edit [〜#〜]

遅さの原因は何かを理解しました

a)サーバーがデータを返すが、リクエストを完了する前にリクエストを中断した場合、タイムアウトは無視され、実行がcatchブロックに到達するExceptionを返すまでスタックします。これがこのメソッドの速度低下の原因です。 、まだこれを回避するための有効な解決策が見つかりませんでした。

b)Androidデバイスを起動し、接続なしでアプリを開くと、インターネット接続がアクティブな状態でアプリが開かれ、デバイスがインターネット接続を失った場合も同じようになります)、false値が正しく返されますケースAのこと(アプリを終了して再起動しようとした場合...理由がわかりません。何かがキャッシュされたままになっていると思います)

これはすべて、_Java URLConnection_が読み取り時にフェイルセーフタイムアウトを提供しないという事実に関連しているようです。 このリンク のサンプルを見ると、スレッドを使用して何らかの方法で接続を中断することがわかりましたが、サンプルのように単にnew Thread(new InterruptThread(Thread.currentThread(), con)).start();行を追加しても何も変わりません。

22
AndreaF
_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;
}
_

またはランタイムを使用して:

_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;
}
_

isReachable()を試すことができますが、 バグが報告されていますこのコメントはisReachable()にはroot権限が必要だと言っています があります:

_try {
    InetAddress.getByName("your server url").isReachable(2000); //Replace with your name
    return true;
} catch (Exception e)
{
    return false;
}
_
23
Sagar Pilkhwal
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;
        }
    }
5
BSavaliya

生のソケットを使用してみましたか?

下位層にあるため、より高速に実行されるはずです

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;
}
0
eridal

先月も同様の問題がありましたが、オプションの例を使って誰かが手伝ってくれました。同じことを提案したい

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;
        }
    }

あなたのURLサーバーが利用可能であるよりもtrueを返す場合、現在利用できません。

0
A_rmas

以下のコードは、Webページが利用可能になるまで待機します。

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);
        }
    }
0
khajappa

「eridal」で述べたように、それはより速く、ソケットを開く必要があります。ただし、サーバーがホストとポートでリッスンしていることを通知するだけですが、確かにHTTPまたは不正な要求(ジャンク)を記述する必要があるため、HTTP/1.1 400 Bad Requestを取得する必要があります。返された最初の行にHTTPが含まれている場合は、サーバーがHTTPサーバーであることを確認します。これにより、サーバーとHTTPサーバーが確実に使用可能になります。

これは、eridalによる上記の答えの拡張です。

0
Ironluca

ここ 作家はこれを提案します:

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;
}

とにかくリクエストしたい自分のページにpingすることはできませんか? 「インターネット接続が利用可能」と自分のサーバーが到達可能であることを区別したい場合は、両方をチェックすることもできます。

リンクを読んでください。それはとても良いようです

編集:それを使用する私の経験では、この方法ほど速くありません:

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

それらは少し異なりますが、インターネットへの接続を確認するだけの機能では、接続変数のために最初の方法が遅くなる場合があります。

0
Emad