2009-09-18 11 views
34

Estoy desarrollando una aplicación que se conecta al servidor. Por ahora, el inicio de sesión y la transmisión de datos funcionan bien si el servidor está disponible. El problema surge cuando el servidor no está disponible. En este caso, el método envía una solicitud de inicio de sesión y espera la respuesta.Android: ¿Cómo comprobar si el servidor está disponible?

¿Alguien sabe cómo comprobar si el servidor está disponible (visible)?

El pseudocódigo de la lógica simple que tiene que ser implementada es la siguiente:

  1. cadena serverAddress = (valor leído del archivo de configuración) // ha hecho
  2. serverAvailable booleano = (comprobar si el servidor serverAddress está disponible) // tiene que ser implementado
  3. (Aquí viene la lógica que depende de serverAvailable)
+0

puede ver: http://stackoverflow.com/a/18845416 para obtener una buena forma de hacerlo. (me ayudó :)) – yossico

Respuesta

45

probablemente necesita código Java ya que él es que tr n Android. El equivalente de Java, que creo que funciona en Android, debería ser:

InetAddress.getByName(host).isReachable(timeOut) 
+29

¡Tenga en cuenta que esto no siempre funciona! [De los documentos] (http://developer.android.com/reference/java/net/InetAddress.html#isReachable%28int%29): "Este método primero intenta usar ICMP (PETICIÓN DE ECO DE ICMP). Cuando el primer paso falla, se establece una conexión TCP en el puerto 7 (Echo) del host remoto ". He descubierto que muchos dispositivos Android no son compatibles con ICMP, y muchos servidores no aceptan conexiones TCP a través del puerto 7. 'isReachable()' simplemente agota el tiempo mientras el servidor es alcanzable. –

+3

Si este método no funciona, puede probar: http://stackoverflow.com/a/18845416 – yossico

+0

También necesita usarlo de forma asíncrona si se usa en el hilo principal –

2

¿Estás trabajando con HTTP? A continuación, puede establecer un tiempo de espera de su conexión HTTP, tales como:

private void setupHttpClient() { 
    BasicHttpParams httpParams = new BasicHttpParams(); 

    ConnManagerParams.setTimeout(httpParams, CONNECTION_TIMEOUT); 
    //... 

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(
      httpParams, schemeRegistry); 
    this.httpClient = new DefaultHttpClient(cm, httpParams); 
} 

Si a continuación, ejecutar una solicitud, recibirá una excepción después de que el tiempo de espera determinado.

0

Ah, no no, el código en Java no funciona: InetAddress.getByName ("fr.yahoo.com"). IsReachable (200) aunque en el LogCat vi su dirección IP (lo mismo con 20000 ms de tiempo de espera).

Parece que el uso del comando 'ping' es conveniente, por ejemplo:

 
Runtime runtime = Runtime.getRuntime(); 
Process proc = runtime.exec("ping fr.yahoo.com -c 1"); // other servers, for example 
proc.waitFor(); 
int exit = proc.exitValue(); 
if (exit == 0) { // normal exit 
    /* get output content of executing the ping command and parse it 
    * to decide if the server is reachable 
    */ 
} else { // abnormal exit, so decide that the server is not reachable 
    ... 
} 
+11

Visto que está etiquetado como Android, me gustaría salvar a cualquiera el esfuerzo de probar esto como abrir sockets sin formato en Linux requiere permisos de root. Por lo tanto, * no funcionará * en la mayoría de los dispositivos sin raíz. He encontrado que funciona varios dispositivos HTC, pero otros simplemente devuelven "ping: icmp socket abierto: Operación no permitida". –

17

Con una simple prueba de ping-como, esto funcionó para mí:

static public boolean isURLReachable(Context context) { 
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo netInfo = cm.getActiveNetworkInfo(); 
    if (netInfo != null && netInfo.isConnected()) { 
     try { 
      URL url = new URL("http://192.168.1.13"); // Change to "http://google.com" for www test. 
      HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); 
      urlc.setConnectTimeout(10 * 1000);   // 10 s. 
      urlc.connect(); 
      if (urlc.getResponseCode() == 200) {  // 200 = "OK" code (http connection is fine). 
       Log.wtf("Connection", "Success !"); 
       return true; 
      } else { 
       return false; 
      } 
     } catch (MalformedURLException e1) { 
      return false; 
     } catch (IOException e) { 
      return false; 
     } 
    } 
    return false; 
} 

no hacer olvide ejecutar esta función en un hilo (no en el hilo principal).

+0

Esto funciona bien para mí también. Gracias. –

+0

Lo sentimos, todavía estaba buscando una solución. Lo que descubrí es que ejecutar esto en segundo plano consume mucho ancho de banda ya que supongo que está descargando la página while en segundo plano. Así que ahora lo intento con un proceso de ping. – Ayyappa

+0

Ok, ya veo, gracias por los detalles. Siéntase libre de editar mi respuesta, o para proporcionar la suya;) –

5

puede utilizar

InetAddress.getByName(host).isReachable(timeOut) 

pero no funciona bien cuando anfitrión no está respondiendo en TCP 7. Puede comprobar si el host está disponible en ese puerto lo que necesita con la ayuda de esta función:

public static boolean isHostReachable(String serverAddress, int serverTCPport, int timeoutMS){ 
    boolean connected = false; 
    Socket socket; 
    try { 
     socket = new Socket(); 
     SocketAddress socketAddress = new InetSocketAddress(serverAddress, serverTCPport); 
     socket.connect(socketAddress, timeoutMS); 
     if (socket.isConnected()) { 
      connected = true; 
      socket.close(); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     socket = null; 
    } 
    return connected; 
} 
3
public static boolean IsReachable(Context context) { 
    // First, check we have any sort of connectivity 
    final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    final NetworkInfo netInfo = connMgr.getActiveNetworkInfo(); 
    boolean isReachable = false; 

    if (netInfo != null && netInfo.isConnected()) { 
     // Some sort of connection is open, check if server is reachable 
     try { 
      URL url = new URL("http://www.google.com"); 
      //URL url = new URL("http://10.0.2.2"); 
      HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); 
      urlc.setRequestProperty("User-Agent", "Android Application"); 
      urlc.setRequestProperty("Connection", "close"); 
      urlc.setConnectTimeout(10 * 1000); 
      urlc.connect(); 
      isReachable = (urlc.getResponseCode() == 200); 
     } catch (IOException e) { 
      //Log.e(TAG, e.getMessage()); 
     } 
    } 

    return isReachable; 
} 

intentarlo, el trabajo para mí y no se olvide actived android.permission.ACCESS_NETWORK_STATE

+1

No funciona conmigo. El valor de isReachable siempre es falso. –

+0

por favor conozca su conexión o verifique la conexión del servidor –

+0

se ve bien. modificará un poco y pruébalo. Gracias –

2
public boolean isConnectedToServer(String url, int timeout) { 
try{ 
    URL myUrl = new URL(url); 
    URLConnection connection = myUrl.openConnection(); 
    connection.setConnectTimeout(timeout); 
    connection.connect(); 
    return true; 
} catch (Exception e) { 
    // Handle your exceptions 
    return false; 
} 
} 
Cuestiones relacionadas