Выполнение IPerf3 из Android 7 не работает

Я создаю приложение для Android, которое позволяет выполнять некоторые команды iperf. Для этого я получил версию 3 исходного кода проекта IPerf C и кросс-компилировал его с помощью следующих команд:

> make clean
> ./configure --host=arm-linux --prefix=/home/laboPC/Downloads CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ CFLAGS="-static" CXXFLAGS="-static" LDFLAGS="-pie -fuse-ld=bfd"
> make

После кросс-компиляции у меня получился бинарный файл, который я поместил в папку assets в своем андроид-проекте.

Для использования IPerf из Android я создаю копию двоичного файла следующим образом:

private String binariePath = context.getApplicationInfo().dataDir + "/iperf3";

private void setupBinaries(){
     InputStream in = context.getResources().openRawResource(R.raw.iperf3);
     OutputStream out = new FileOutputStream(binariePath);
     byte[] buf = new byte[1024];
     int len;

     while ((len = in.read(buf)) > 0) {
         out.write(buf, 0, len);
     }
     in.close();
     out.flush();
     out.close();
     Runtime.getRuntime().exec("chmod 751 " + binariePath);
}

Затем я использую объект Runtime для выполнения команды iperf следующим образом:

public String runClient (String server, String argument) {
    try {
       setupBinaries();

        process = Runtime.getRuntime().exec(binariePath + " -c " + server + " " + argument);
        BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()));

        final StringBuilder result = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line + "\n");
        }
        reader.close();
        process.destroy();
        return result.toString();

    } catch (IOException e) {
        Log.d("IPERF", e.getLocalizedMessage());
        return e.getLocalizedMessage();
    }
}

Все работает нормально, кроме Android 7.0. Когда я запускаю свое приложение на Nexus 5X в Android 7, кажется, что команда iperf не выполняется, а моя переменная result пуста.

Я проверил, что Runtime.exec() отлично работает в Android 7 и что двоичный файл правильно копируется в каталог данных приложения.

У всех есть идея, что не так в моем процессе? Верны ли мои команды для компиляции проекта IPerf?

Спасибо за вашу помощь.

ИЗМЕНИТЬ

В следующих темах я обнаружил, что Android 6.0 и выше могут выполнять двоичные файлы, скомпилированные с параметром -fPIC:

android ndk: являются ли -fPIC и -pie взаимоисключающими?

Положение независимых исполняемых файлов и Android Lollipop

Поэтому я попытался скомпилировать свой проект C с помощью этой командной строки:

./configure --host=arm-linux --prefix=/home/laboPC/Downloads CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ CFLAGS="-static -fPIC" CXXFLAGS="- статический" LDFLAGS="-pie -fuse-ld=bfd"

Я думаю, что с моей командной строкой что-то не так, но я не знаю, что. Кто-нибудь может помочь мне определить, что я ошибаюсь в своей командной строке?


person Red    schedule 05.12.2016    source источник
comment
Проверьте свой двоичный файл прямо из оболочки устройства: $ adb push iperf3 /data/local/tmp; adb shell "chmod +x /data/local/tmp/iperf3"; adb shell "/data/local/tmp/iperf3 -c <server> <argument>".   -  person Sergio    schedule 05.12.2016
comment
Спасибо за Ваш ответ. Я делаю это и получаю CANNOT LINK EXECUTABLE "/data/local/tmp/iperf3": /data/local/tmp/iperf3 : has text relocations. И если я сделаю это на устройстве, отличном от Nexus 5X, я получу iperf3: error - unable to create a new stream : Permission denied   -  person Red    schedule 05.12.2016
comment
Попробуйте добавить -fpie к CFLAGS, поскольку опция компоновщика -pie поможет, только если связанный код не зависит от позиции. Также дважды проверьте, что эти флаги передаются компилятору и компоновщику.   -  person Sergio    schedule 05.12.2016
comment
Я добавляю параметр -fpie следующим образом: ./configure --host=arm-linux --prefix=/home/laboPC/Downloads CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ CFLAGS="-static -fpie" CXXFLAGS="-static" LDFLAGS="-pie -fuse-ld=bfd" и получаю warrning linker : /data/local/tmp/iperf3 : unsupported flag DT_FLAGS_1=0x8000000. /data/local/tmp/iperf3 : has text relocations   -  person Red    schedule 05.12.2016


Ответы (2)


Я нашел ваш вопрос, и он помог мне собрать iperf3 для Android, но столкнулся с той же проблемой.
Используете ли вы наборы инструментов для сборки из репозитория Ubuntu? Если да, встроенные двоичные файлы не будут работать на Android 7.0, потому что они используют старую версию наборов инструментов сборки. Вам нужно будет собрать двоичные файлы с самой последней версией NDK. (сейчас r13b)

Как я это решил:
-Поместил все исходники iperf3 из папки src в папку jni
-Создал файлы Android.mk и Application.mk, которые я опубликую ниже, в той же папке вместе с другими файлами.
- Внутри папки jni я запустил ndk-build и, вуаля, все бинарники в папке /libs, работающие даже на Android 7.0 (выберите бинарники, поместите в папку с ресурсами и реализуйте свою стратегию, чтобы загрузить правильный бинарник для правильного abi, или просто скачайте бинарный файл armeabi и загрузите его в свое приложение)

Совет: iperf3 использует папку для кэширования результатов, которая недоступна для Android. Для работы вам потребуется изменить эту папку:
https://github.com/esnet/iperf/blob/670c18584bcf7a285f3561eb7ea38cc53600d0ab/src/iperf_api.c#L2621

Android.mk: (думаю, что на этот скрипт ставить файлы .h не обязательно)
http://pastebin.com/fPsn0wsD

Application.mk:
http://pastebin.com/sgSsGNqB

Я рекомендую использовать ndk-build для сборки библиотеки, чтобы упростить сборку iperf3 для разных архитектур, таких как x86.

person Thiago    schedule 11.01.2017
comment
Я собрал iperf3 по вашей инструкции. Не могли бы вы дать рекомендации по запуску команды iperf с помощью Java-страницы Android. - person Mercy Angel; 11.12.2019

Если вы получите сообщение об ошибке:

iperf3: error - unable to create a new stream: Permission denied

Or:

iperf3: error - unable to create a new stream: No such file or directory

Вы можете сделать то, что я написал здесь: https://stackoverflow.com/a/58578227/12279527

person ArtemYashin    schedule 27.10.2019