iperf,测试网络性能的,不同于 webrtc里面的gcc 算法预估网络带宽,iperf是实际占用网络来传输数据测量实际的网络性能。
官网:https://iperf.fr/
官方就有 android 的下载 https://iperf.fr/iperf-download.php#android, 但是看起来要访问 play.google. 墙。急用,怎么自己拿源码来ndk 编译一下。
1. 最适配的方式,应该是用 configure + make, configure来配置ndk编译器。 (ubuntu环境下) 没有环境,不想太折腾
2. 在AndroidStudio 上用cmake 编译
3. 还是用比较熟悉的 Android.mk , 在AS中编译
目录
一:下载源码
二:AS 创建一个空的demo,src/main 目录下建一个jni, 把源码解压到这里, 然后编写 Android.mk 来编译。(如果直接使用ndk-build 命令,就不需要AS了。)
在app 的build.gradle中手动指定Android.mk 文件位置,使用的ndk版本,以及要编译的平台
Android.mk
对源码需要做一点头文件的修改
1. 在src 中加上 iperf_config.h
2. src 目录下 version.h 同上,来源为version.h.in
3.修改源码里面一个 字符串,临时文件的路径
最后,build
1. 测试带宽
2. 测试udp 丢包
一:下载源码
发布的只有3.1.3 iPerf - Download iPerf3 and original iPerf pre-compiled binaries
二:AS 创建一个空的demo,src/main 目录下建一个jni, 把源码解压到这里, 然后编写 Android.mk 来编译。(如果直接使用ndk-build 命令,就不需要AS了。)
在app 的build.gradle中手动指定Android.mk 文件位置,使用的ndk版本,以及要编译的平台
android {
compileSdk 32
defaultConfig {
applicationId "com.example.iperf3"
minSdk 23
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// 平台指定
ndk{
abiFilters "arm64-v8a"
}
}
// ndk 版本指定(可不选,AS会根据gradle版本指定默认)
// ndkVersion "22.0.7026061"
ndkVersion '24.0.8215888'
// ndkVersion "21.1.6352462"
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// Android.mk 文件指定
externalNativeBuild{
ndkBuild{
path file("src/main/jni/Android.mk")
}
}
}
Android.mk
LOCAL_PATH := $(call my-dir)
#-------------------iperf3-----
include $(CLEAR_VARS)
LOCAL_MODULE := iperf3
MY_SRC_PATH = iperf-3.1.3/src
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(MY_SRC_PATH)
#LOCAL_SRC_FILES := $(call all-c-files-under, iperf-3.1.3/src) 没效果??
LOCAL_SRC_FILES += $(MY_SRC_PATH)/cjson.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_api.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_client_api.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_error.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_locale.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_sctp.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_server_api.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_tcp.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_udp.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/iperf_util.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/main.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/net.c
#LOCAL_SRC_FILES += $(MY_SRC_PATH)/t_timer.c
#LOCAL_SRC_FILES += $(MY_SRC_PATH)/t_units.c
#LOCAL_SRC_FILES += $(MY_SRC_PATH)/t_uuid.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/tcp_info.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/tcp_window_size.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/timer.c
LOCAL_SRC_FILES += $(MY_SRC_PATH)/units.c
LOCAL_LDFLAGS += -pie -fPIE
include $(BUILD_EXECUTABLE)
#include $(BUILD_STATIC_LIBRARY)
对源码需要做一点头文件的修改
本来这些头文件是 configure 命令自动添加上去的,我们没有configure,需要自己动手补上。
1. 在src 中加上 iperf_config.h
(来源是源码中的 iperf_config.h.in, configure命令以这个为输入,定义了一些宏, 不确定的话,直接把这个iperf3搞到ubuntu上,运行一下./configure 可以得到一版,然参考修改) 可直接参考:
iperf_config.h
/* src/iperf_config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `cpuset_setaffinity' function. */
#undef HAVE_CPUSET_SETAFFINITY
/* Have CPU affinity support. */
#undef HAVE_CPU_AFFINITY
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Have IPv6 flowlabel support. */
#undef HAVE_FLOWLABEL
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netinet/sctp.h> header file. */
#undef HAVE_NETINET_SCTP_H
/* Define to 1 if you have the `sched_setaffinity' function. */
#undef HAVE_SCHED_SETAFFINITY
/* Have SCTP support. */
#undef HAVE_SCTP
/* Define to 1 if you have the `sendfile' function. */
#undef HAVE_SENDFILE
/* Have SO_MAX_PACING_RATE sockopt. */
#undef HAVE_SO_MAX_PACING_RATE
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if the system has the type `struct sctp_assoc_value'. */
#undef HAVE_STRUCT_SCTP_ASSOC_VALUE
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Have TCP_CONGESTION sockopt. */
#undef HAVE_TCP_CONGESTION
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Name of package */
#define PACKAGE "iperf"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "https://github.com/esnet/iperf"
/* Define to the full name of this package. */
#define PACKAGE_NAME "iperf"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "iperf 3.1.3"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "iperf"
/* Define to the home page for this package. */
#define PACKAGE_URL "http://software.es.net/iperf/"
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.1.3"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "3.1.3"
2. src 目录下 version.h 同上,来源为version.h.in
/*
* iperf, Copyright (c) 2014, The Regents of the University of
* California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved.
*
* If you have questions about your rights to use or distribute this
* software, please contact Berkeley Lab's Technology Transfer
* Department at TTD@lbl.gov.
*
* NOTICE. This software is owned by the U.S. Department of Energy.
* As such, the U.S. Government has been granted for itself and others
* acting on its behalf a paid-up, nonexclusive, irrevocable,
* worldwide license in the Software to reproduce, prepare derivative
* works, and perform publicly and display publicly. Beginning five
* (5) years after the date permission to assert copyright is obtained
* from the U.S. Department of Energy, and subject to any subsequent
* five (5) year renewals, the U.S. Government is granted for itself
* and others acting on its behalf a paid-up, nonexclusive,
* irrevocable, worldwide license in the Software to reproduce,
* prepare derivative works, distribute copies to the public, perform
* publicly and display publicly, and to permit others to do so.
*
* This code is distributed under a BSD style license, see the LICENSE
* file for complete information.
*/
#define IPERF_VERSION "3.1.3"
3.修改源码里面一个 字符串,临时文件的路径
iperf_aip.c::
/tmp/ 这个是linux路径,android 上没有,直接改为 /data/ 或者就是当前运行目录。
最后,build
在app\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a 得到可执行文件, push 到/data/xx上去运行。
附上测试命令:
1. 测试带宽
服务端:#iperf3 -s -p 5001
-s 表示作为服务端, -p 指定端口号
客户端:#iperf3 -c 127.0.0.1(服务器IP) -P 4 -t 30 -i 2 -p 5001
-c 表示作为客户端, 后面跟服务端ip, -P (大写) 表示process, 同时并发任务数,这里是4, -t 表示测试持续时间,单位秒。 -i 表示每隔2秒报一次结果。 -p 端口号
2. 测试udp 丢包
(udp无连接,发快网络带宽不够导致丢包,所以测udp在限制带宽的情况下丢包率)
服务端:#iperf3 -s -p 5001
客户端: #iperf3 -u -c 192.168.43.129 -p 8989 -b 100M -t 30
-u 指定使用udp, -c 表示作为客户端 -b 限制在100Mbit