Приложение Ping в Android
Я создаю приложение, которое реализует некоторые функции команды "ping". Проблема в том, что я не знаю, какую библиотеку/библиотеки использовать в ANDROID.
у кого есть идея?
Я посетил эти ссылки stackoverflow, но они не очень помогли.
Ответы
Ответ 1
Я использовал следующий код для 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;
}
Здесь, в URL-адресе, вам необходимо передать адрес, по которому вы хотите выполнить ping.
Ответ 2
Спасибо за исследование проблемы. Вопросы, с которыми вы связались (и многие другие на SO), все приводят к решениям использования либо исполняемого файла ping системы, либо попытка сомнительного InetAddress.isReachable. Существует, однако, третий вариант - если вы хотите добавить небольшой собственный код.
Недавно я реализовал функции ICMP Echo (ping) для приложения Android VPN. Я не мог использовать исполняемый файл "ping" системы, поскольку пакеты ICMP, которые он отправил, были пойманы моей VPN, и, во всяком случае, я хотел иметь возможность отправлять ICMP-пакеты из моей сети во внешний мир и получать ответы.
Метод InetAddress.isReachable не работал у меня вообще (всегда возвращался false), как было подробно обсуждено в SO, например. здесь и здесь.
Решением, к которому я пришел, является использование собственного кода для создания ICMP-сокета, который я использовал для отправки и получения ICMP-пакетов (Echo-запросы и ответы для ping "). Ядро Linux поддерживает (с 2011 года) создание ICMP-сокетов без каких-либо специальных привилегий. Новый ICMP-сокет создается как сокет Datagram с протоколом PROT_ICMP. Хороший пример реализации в C можно увидеть в этом ответе.
Функциональность сокета ICMP была портирована на Android и даже использовалась в "ping" . На самом деле было высказано предположение, что его можно использовать для исправить реализацию InetAddress.isReachable().
Java API не поддерживает эту функцию, но, используя собственный код, можно открыть ICMP-сокеты. Я использовал JNA для доступа к функциям libC, которые мне нужны (socket(), close(), sendto(), recvfrom(), poll(), и т.д.). Я полагаю, JNI будет работать так же хорошо.
Чтобы обойти ограничение VPN, файловый дескриптор сокета должен быть защищен с помощью VpnService.protect(int).
Есть несколько предостережений, как описано в статье LWN:
- Не забудьте проверить, что ваша система разрешает сокеты ICMP, читая (и, возможно, настраивая) содержимое "/proc/sys/net/ipv4/ping_group_range".
- Ядро изменяет поле "идентификатор" в заголовке ICMP, вам нужно будет reset его (и пересчитать контрольную сумму), если вы намереваетесь перенаправить пакет ответа в исходный запросчик.
Ответ 3
Я реализовал "ping" в чистой Android Java и разместил его на gitlab. Он имеет несколько полезных функций, таких как возможность привязки к определенной сети.
https://github.com/dburckh/AndroidPing