2014-09-12 32 views
16

我有一個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; 
    } 
} 

返回在過程結束時正確的值,如果服務器不可用有點太慢了。

編輯

我已經明白了是緩慢的原因

一)如果服務器返回了一些數據,但中斷請求之前完成請求超時被忽略,並卡住,直到返回一個Exception這導致執行到達catch塊,這是這種方法緩慢的原因,但我還沒有找到有效的解決方案來避免這種情況。

b)如果我啓動android設備並在沒有連接的情況下打開應用程序,則錯誤值將被正確返回,如果應用程序在互聯網連接處於活動狀態並且設備失去其Internet連接時打開,則會發生與情況A相同的情況(也如果我試圖終止並重新啓動應用程序...我不知道爲什麼,我想這東西仍然緩存)

所有這些似乎與事實Java URLConnection不提供故障安全超時讀取。看看this link的示例,我已經看到使用線程以某種方式中斷連接,但如果我簡單地添加new Thread(new InterruptThread(Thread.currentThread(), con)).start();這一行,就像示例中沒有任何更改。

+1

嘗試使用getResponseMessage()或getResponseCode() – KOTIOS 2014-09-12 09:59:20

+0

錯誤的請求意味着您的URL無效,但並非服務器不可用 – 2014-09-12 11:03:46

+0

@mtetno您能否給我更多詳細信息用戶回答了類似的問題,例外的相關嘗試catch塊 – AndreaF 2014-09-12 15:59:59

回答

2
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; 
     } 
    } 
+0

此代碼的作品,但速度一樣慢,等待嘗試捕獲塊 – AndreaF 2014-09-12 15:58:38

0

您是否嘗試過使用原始套接字?

應該運行得更快,因爲它是在下層

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

的異常與此代碼應用程序崩潰並獲取端口超出範圍異常 – AndreaF 2014-09-18 16:43:07

14
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()但有一個bug filed for itthis 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; 
} 
+0

第一個示例具有相同的問題,我已發佈的代碼(工作但服務器沒有給出響應時很慢),第二個示例返回總是假的 – AndreaF 2014-09-18 19:15:50

+0

我編輯了我的答案,也嘗試'ping -c 1 www.serverURL.com' – 2014-09-19 06:06:32

+0

我在ping後添加了-1 c,但返回始終爲false,儘管第一個方法在同一個鏈接上返回正確爲true – AndreaF 2014-09-19 17:16:26

0

正如'eridal'所提到的那樣,應該更快,打開插座;但是,它只會告訴你一臺服務器正在監聽主機和端口,但是可以肯定的是,你需要編寫HTTP或者一個錯誤的請求(垃圾),你應該得到HTTP/1.1 400錯誤請求。通過讀取返回的第一行,如果它包含HTTP,那麼您確定該服務器是一個HTTP服務器。這樣你就可以確定服務器和HTTP服務器都可用。

這是對eridal的上述回答的擴展。

-1

上個月我有類似的問題,有人幫我一個可選的例子。我想建議你一樣

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

如果返回true,則表示您的url服務器可用,否則當前不可用。

+0

或者您可以檢查 http://stackoverflow.com/questions/ 25541940/android-check-condition-for-server-down – 2014-09-19 05:56:06

+0

正如我在我的問題中所說的,此代碼rteturns總是虛假的,與我的鏈接 – AndreaF 2014-09-20 11:51:14

+0

您的鏈接會將您帶到鏈接「http://website.1and1.com/#top 「所以只能使用** website.1and1.com **。它返回true – 2014-09-22 07:39:39

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

試試這個代碼

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

下面的代碼一直等待,直到網頁可用:

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

here筆者提出這樣的:

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我自己的頁面,我想要求嗎?當然!如果您想區分「可用的互聯網連接」和您自己的服務器可達,您甚至可以同時檢查這兩個選項。

閱讀鏈接。它看起來很不錯

編輯:我在使用它的EXP ,它的速度比不上這個方法:

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

他們有點不同,但在功能只是檢查互聯網的連接由於連接變量,第一種方法可能會變慢。