Главная » Android » Программирование » Попытка написать ping и traceroute

Попытка написать ping и traceroute

29 июня 2013

Дочитал начатую еще в 2010 году книгу по программированию для платформы Android, “Teach Yourself Android Application Development in 24 Hours”. Название из серии “24 часа из жизни чайника” ;) , но на деле эта книга показалась мне наиболее краткой и доступной. Конечно же, одной этой книги недостаточно, также не хватает общих знаний по Java. Но я немного подумал и решил, что браться за новую книгу я пока не буду, иначе процесс изучения теории может затянуться до бесконечности. Надо переходить к практике, а уже потом заходить на следующий круг чтения.

Ок, сказано-сделано. Попробовал закодировать кусочек одной идеи, для которой мне необходимо реализовать функционал двух сетевых утилит: ping и traceroute.

Три дня поиска информации и попыток запустить различный программный код, в итоге сделаны следующие выводы:

В текущем API (java.net) для android нет поддержки ICMP и RAW сокетов. То есть, нет возможности создать IP пакеты с произвольным заголовком. Это важно для реализации алгоритма traceroute, когда вначале нужно отправить пакеты с временем жизни (TTL) = 1, затем 2 и так далее.
Я не смог найти готовых сторонних библиотек для android, которые обеспечивали бы собственный функционал Raw Sockets. Есть исходники библиотеки для linux под GPL лицензией, java и c++ код, но их нужно переносить на android. А это, к сожалению, работа далеко не на один день для моей текущей квалификации.

Но нашлось обходное решение: запустить ping и traceroute как внешние процессы. Вначале это решение показалось мне некрасивым: поверх окна моего приложения будет запускаться какое-то консольное окно утилиты? Но оказалось, что во-первых, никаких консольных окон не появляется, и во-вторых, при запуске внешнего процесса к нему можно подключить потоки ввода и вывода. То есть, я могу спокойно перехватить вывод утилиты в поток, отформатировать его и вывести в свое приложение.

В качестве примера, три строки запуска утилиты ping:
ProcessBuilder pb = new ProcessBuilder( “ping”, “-c 2″, “android.com” );
Process process = pb.start();
InputStream es = process.getErrorStream();

Кстати, час прокувыркался с аргументами. Пока не разделил их на отдельные строки, ping методично ругался на неправильное имя хоста и выводил экран подсказки. Почему именно так – загадка природы.