Detecta la conexión a internet usando Java

Posible duplicado:
¿Cómo comprobar si la conexión a Internet está presente en Java?

Quiero ver si alguien tiene una manera fácil de detectar si hay una conexión a Internet cuando se usa Java. La aplicación actual usó el método “InternetGetConnectedState” en la DLL WinInit para Windows, pero mi aplicación debe ser multiplataforma para el funcionamiento de mac y de esta manera no funcionará. No sé nada de JNI para usar DLL en Java y se volvió frustrante rápidamente.

Solo las formas en que podía pensar eran intentar abrir una conexión URL a un sitio web y, si eso falla, devolver falso. Mi otro camino está abajo, pero no sabía si esto era generalmente estable. Si desenchufo mi cable de red, obtengo una excepción de excepción desconocida cuando trato de crear InetAddress. De lo contrario, si el cable está conectado, obtengo un objeto InetAddress válido. Todavía no he probado el código a continuación en un mac.

Gracias por cualquier ejemplo o consejo que pueda proporcionar.

ACTUALIZACIÓN: El bloque de código final está en la parte inferior. Decidí seguir el consejo de una solicitud HTTP (en este caso, Google). Es simple y envía una solicitud al sitio para que se devuelvan los datos. Si no puedo obtener ningún contenido de la conexión, no hay internet.

public static boolean isInternetReachable() { try { InetAddress address = InetAddress.getByName("java.sun.com"); if(address == null) { return false; } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } return true; } 

Bloque de código final:

 //checks for connection to the internet through dummy request public static boolean isInternetReachable() { try { //make a URL to a known source URL url = new URL("http://www.google.com"); //open a connection to that source HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection(); //trying to retrieve data from the source. If there //is no connection, this line will fail Object objData = urlConnect.getContent(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } return true; } 

Ese es un enfoque perfectamente razonable para resolver el problema. Lo malo es que realmente estás probando DNS en lugar de probar toda la red, pero en la práctica a menudo puedes seguir tratando a esos como equivalentes.

Otra cosa que debes recordar es que deberás configurar una propiedad del sistema para desactivar el almacenamiento en caché de dns en el tiempo de ejecución de Java. De lo contrario, puede continuar informando que la red está activa en función de los datos almacenados en caché (aunque esté inactivo).

Otro enfoque sería abrir realmente una solicitud HTTP a alguna dirección de red como esta de vez en cuando.

Debo agregar que aunque el bloque de código final dado arriba es bueno, tiene un defecto: es posible que tarde mucho tiempo en contactarse con la dirección especificada, pero la dirección aún es alcanzable.

En mi caso, cuando probaba con una dirección, el método devolvía verdadero, pero demoraba 10 segundos o más para obtener una respuesta. En este caso, el servidor era alcanzable, pero no con fines útiles ya que la conexión era muy lenta. Esto ocurre porque el tiempo de espera predeterminado para HttpURLConnection es 0 o infinito.

Por esta razón, le recomiendo que haga la verificación de la urlConnect.setConnectTimeout(1000); de la interfaz de usuario, y agregue urlConnect.setConnectTimeout(1000); antes de llamar a urlConnect.getContent();

De esta forma sabrá que la dirección es alcanzable, y que no tomará 5 años descargar un archivo de 10k.

(Por supuesto, puede querer cambiar el tiempo de espera para satisfacer sus necesidades)

También recomendaría no verificar una dirección genérica (google.com, etc.) a menos que su progtwig generalmente acceda a más de unos pocos dominios. Si solo está accediendo a uno o dos, verifique ese dominio.

Tenga en cuenta que podría devolver false si java.sun.com no responde. En este caso, debe verificar otro sitio para estar seguro.

No lo he probado, pero sugiero consultar java.net.NetworkInterface.getNetworkInterfaces (). Esto devuelve una enumeración de todas las interfaces de red en la máquina, o nula si no hay ninguna.

No estoy seguro de si es seguro asumir que una respuesta no nula garantiza una conexión de red válida. Dependiendo de sus necesidades, puede o no necesitar filtrar direcciones de bucle invertido (lo que creo que podría hacer con java.net .NetworkInterface.getInetAddresses () en cada NetworkInterface devuelto, y luego llamar a InetAddress.isLoopbackAddress () en cada uno.)

La única forma de asegurarse de que puede llegar a un servicio determinado es realizar una solicitud ficticia a ese servicio. Los pings pueden ser bloqueados por firewalls. Algunos servidores pueden ser accesibles, otros no. Si necesita hablar con un servicio web, tenga una página estática para devolver para estas solicitudes.

Además, recuerde preguntar al usuario antes de tratar de comunicarse.

La pregunta realmente no tiene un significado. No existe una “conexión a Internet”. Tienes que intentar crear uno. La API de Windows a la que se hace referencia solo le dice si su módem está marcado o no, y he visto que realmente causa números de acceso telefónico, lo cual no es exactamente la idea. No es que haya tenido un dial-in durante los últimos 8 años más o menos.

Un problema con la primera solución es que InetAddress tiene un caché, por lo que, cuando pierde la conexión para las próximas invocación, el nombre se resuelve mediante el caché de Java. Con el enfoque de conexión de URL tienes el problema de que usas getContent que debería buscar html para que tengas consumo de datos. Si las invocaciones se realizan con mucha frecuencia, esto podría ser un problema (más aún si no tiene un plan de datos ilimitado en el dispositivo que ejecuta el software).

Creo que la mejor solución sería hacer una conexión TCP al puerto 80 y cerrarla inmediatamente después de una conexión exitosa. Eso se comportaría como el código final pero tendría mucho menos tráfico.