Aplicación de ping en Android

Estoy haciendo una aplicación que implementará algunas características del comando “ping“. El problema es que no tengo idea de qué biblioteca / bibliotecas usar en ANDROID. Alguien tiene alguna idea para eso?

He visitado estos enlaces de stackoverflow pero no fueron muy útiles.

  • ¿Hay alguna manera de hacer que un dispositivo Android responda a los pings icmp dirigidos a la dirección de difusión?
  • https://stackoverflow.com/questions/5601513/problem-to-do-ping-with-android
  • La depuración de Android InetAddress.isReachable
  • cómo hacer icmp ping en android
  • Cómo hacer ping a IP externa desde Java Android

He usado el siguiente código para hacer ping.

public String ping(String url) { String str = ""; try { Process process = Runtime.getRuntime().exec( "/system/bin/ping -c 8 " + url); BufferedReader reader = new BufferedReader(new InputStreamReader( process.getInputStream())); int i; char[] buffer = new char[4096]; StringBuffer output = new StringBuffer(); while ((i = reader.read(buffer)) > 0) output.append(buffer, 0, i); reader.close(); // body.append(output.toString()+"\n"); str = output.toString(); // Log.d(TAG, str); } catch (IOException e) { // body.append("Error\n"); e.printStackTrace(); } return str; } 

Aquí en la url, debe pasar la dirección en la que desea hacer ping.

Gracias por investigar el problema. Las preguntas a las que se ha vinculado (y muchas otras en SO) conducen a las soluciones de usar el ejecutable ping del sistema o probar el dudoso método InetAddress.isReachable . Sin embargo, existe una tercera alternativa: si está dispuesto a agregar un pequeño código nativo .

Recientemente implementé la funcionalidad ICMP Echo (ping) para una aplicación Android VPN. No pude usar el ejecutable del sistema “ping” ya que los paquetes ICMP que envía fueron capturados por mi VPN, y en cualquier caso, quise poder reenviar los paquetes ICMP de mi red al mundo exterior y recibir las respuestas.

El método InetAddress.isReachable no funcionó para mí en absoluto (siempre devuelto falso), como se ha discutido a fondo en SO, por ejemplo, aquí y aquí .

La solución a la que llegué es el uso de código nativo para crear un socket ICMP, que solía enviar y recibir paquetes ICMP (solicitudes de eco y respuestas para ” ping “). El kernel de Linux admite (desde 2011) la creación de sockets ICMP sin ningún privilegio especial . Se crea un nuevo socket ICMP como un socket Datagram con el protocolo PROT_ICMP. Un buen ejemplo de implementación en C se puede ver en esta respuesta .

La funcionalidad del socket ICMP también se ha portado a Android , e incluso se ha utilizado en el progtwig “ping” . De hecho, se ha sugerido que se puede usar para corregir la implementación de InetAddress.isReachable () .

La API de Java no admite esta funcionalidad, pero al usar código nativo es posible abrir los zócalos ICMP. Usé JNA para acceder a las funciones de libC que necesitaba (socket (), close (), sendto (), recvfrom (), poll (), etc.). Supongo que JNI funcionaría igual de bien.

Para evitar la limitación de VPN, el descriptor de archivo de socket debe protegerse utilizando VpnService.protect (int) .

Hay un par de advertencias, como se explica en el artículo de LWN :

  • Recuerde verificar que su sistema permita los sockets ICMP, leyendo (y posiblemente estableciendo) los contenidos de “/ proc / sys / net / ipv4 / ping_group_range”.
  • El núcleo modifica el campo “identificador” en el encabezado ICMP, tendrá que restablecerlo (y volver a calcular la sum de comprobación) si tiene la intención de reenviar el paquete de respuesta al solicitante original.