Files
iperf3-gui/docs/README.md
T
2026-08-25 19:25:40 +09:00

4.4 KiB

iperf3-gui

A Flutter-based Android GUI wrapper for iperf3, the popular network performance measurement tool.

Architecture

lib/                          # Flutter/Dart application layer
├── main.dart                 # App entry point (MaterialApp)
├── domain/                   # Business logic (platform-independent)
│   ├── models/
│   │   ├── test_configuration.dart   # Server, port, duration, interval, parallel streams
│   │   └── iperf3_result.dart        # Raw output + exit code
│   └── services/
│       ├── iperf3_service.dart       # Dart → MethodChannel bridge (async with Completer)
│       └── iperf3_binary_path_provider.dart   # Deprecated (kept for reference)
└── ui/                       # Presentation layer
    └── features/
        └── test_run/
            ├── test_run_screen.dart          # Server/port inputs + GO button
            └── test_run_view_model.dart      # State machine: idle → running → completed/error

android/app/src/main/
├── kotlin/                     # Kotlin plugin layer
│   └── com/novoyuuparosk/iperf3gui/
│       ├── MainActivity.kt     # Registers IperfRunner as FlutterPlugin
│       └── IperfRunner.kt      # MethodChannel handler → native JNI calls
└── cpp/                        # Native iperf3 library
    ├── CMakeLists.txt          # Compiles iperf3 + cJSON + JNI into libiperf3jni.so
    ├── iperf_jni.c             # JNI bridge: Java String[] → iperf3 API
    ├── iperf/                  # iperf3 3.19 C source tree (see below)
    ├── iperf_config.h          # Generated Android-compatible config header
    └── iperf_config_android.h  # Android-specific compile options

Data Flow

User taps GO
  → Dart TestRunViewModel.runTest(config)
  → Iperf3Service.run(config) via MethodChannel
  → Kotlin IperfRunner.runIperfLive(args, callback)
  → JNI C: java_string_array_to_argv() → iperf_parse_arguments()
  → iperf_run_client(test)
  → Reader thread pipes stdout → CallVoidMethod → Dart onOutput callbacks
  → On completion: Dart Completer resolves with Iperf3Result

Key Design Decisions

JNI Over Process Execution

Android SELinux Enforcing mode blocks execve() from the untrusted_app domain, making Process.start() of external binaries fail with Permission denied. Compiling iperf3 as a shared library linked into the app process eliminates this restriction entirely — iperf3 code runs in-process with no domain transitions needed.

Callback Mechanism

The JNI bridge uses CallVoidMethod on stored jmethodIDs to invoke the Kotlin IperfCallback interface, NOT function pointer casts. Direct function pointer casts caused SIGBUS crashes on ARM due to JNINativeInterface method ID layout differences.

Output Streaming

iperf3 output is redirected via pipe to a background reader thread that attaches to the Java VM via AttachCurrentThread and invokes callbacks via CallVoidMethod. The reader thread frees the state struct on exit; the JNI caller owns the callback object's lifetime.

Async Pattern

Dart uses Completer<Iperf3Result> to await native completion. The MethodChannel callback handler resolves the completer on onComplete, with a timeout fallback that calls stopIperf on the native layer.

iperf3 Source

  • Version: 3.19
  • Location: android/app/src/main/cpp/iperf/
  • Files: Full C source tree including cJSON, headers, man pages, PEM keys
  • Build: CMake compiles into libiperf3jni.so for armeabi-v7a and arm64-v8a
  • Config: iperf_config.h generated from iperf_config.h.in with Android-compatible POSIX/threading macros

Native JNI API

Kotlin Method JNI Signature Purpose
runIperfLive(String[], IperfCallback) runIperfLive Start test with args and callback
forceStopIperfTest(IperfCallback) forceStopIperfTest Graceful stop via shutdown()
isTestRunning() isTestRunning Check if test is in progress

Building

Prerequisites:

  • Flutter 3.47+
  • Android SDK with platform android-36
  • JDK 17
  • NDK r28+
  • CMake 3.22.1
flutter pub get
flutter build apk --debug
adb install build/app/outputs/flutter-apk/app-debug.apk

Dependencies

  • Dart: provider, path_provider
  • Android: CMake external native build
  • Native: iperf3 3.19, cJSON (single file)

License

MIT — bundled iperf3 3.19 is BSD-3-Clause licensed.