iperf工具移植到Android9.0(轉載)

聲明: 轉載自https://www.cnblogs.com/0xcafebabe/p/10685938.htmlhtml

在此僅昨驗證後的記錄。linux

首先下載源代碼,下載地址:https://storage.googleapis.com/google-code-archive-source/v2/code.google.com/iperf/source-archive.zipapi

 

解壓後刪除 Makefile 等不相關的文件,並創建 Android.mk,內容以下:網絡

 

複製代碼ionic

 1 LOCAL_PATH := $(call my-dir)函數

 2 工具

 3 # Device executable.測試

 4 # =========================================================ui

 5 google

 6 include $(CLEAR_VARS)

 7 

 8 LOCAL_MODULE := iperf

 9 

10 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)

11 

12 LOCAL_C_INCLUDES := $(LOCAL_PATH)/src

13 

14 LOCAL_SRC_FILES := $(call all-c-files-under, src)

15 

16 LOCAL_CFLAGS := -Wno-error -DIPERF_HOST=0

17 

18 LOCAL_MODULE_TAGS := debug

19 

20 LOCAL_FORCE_STATIC_EXECUTABLE := true

21 

22 include $(BUILD_EXECUTABLE)

23 

24 

25 # Host executable.

26 # =========================================================

27 

28 include $(CLEAR_VARS)

29 

30 LOCAL_MODULE := iperf_x86

31 

32 LOCAL_C_INCLUDES := $(LOCAL_PATH)/src

33 

34 LOCAL_SRC_FILES := $(call all-c-files-under, src)

35 

36 LOCAL_CFLAGS := -Wno-error -DIPERF_HOST=1

37 

38 LOCAL_LDFLAGS := -static

39 

40 LOCAL_MODULE_TAGS := debug

41 

42 include $(BUILD_HOST_EXECUTABLE)

43 

44 

45 include $(call first-makefiles-under,$(LOCAL_PATH))

複製代碼

接下來打開 src/flowlabel.h 文件,在 struct in6_flowlabel_req 結構體的定義外面加上條件編譯指令,修改後以下所示:

 

複製代碼

 1 // It's defined in bionic/libc/kernel/uapi/linux/in6.h

 2 #if IPERF_HOST

 3 struct in6_flowlabel_req

 4 {

 5     struct in6_addr flr_dst;

 6     __u32   flr_label;

 7     __u8    flr_action;

 8     __u8    flr_share;

 9     __u16   flr_flags;

10     __u16   flr_expires;

11     __u16   flr_linger;

12     __u32   __flr_pad;

13     /* Options in format of IPV6_PKTOPTIONS */

14 };

15 #endif 

複製代碼

IPERF_HOST 這個宏是咱們在 Android.mk 裏面定義的,由於編譯 arm 版 iperf 時,編譯參數中會指定 boinic 的庫,這個宏會出現重定義的狀況。但編譯 x86 版本的 iperf 時,不會連接這些庫,因此這個結構體必須由本程序來定義。

 

 

 

接下來打開 src/iperf_api.c 文件,找到 iperf_new_stream(struct iperf_test *, int) 函數,裏面有這樣的變量定義:

 

char template[] = "/tmp/iperf3.XXXXXX";

因爲 Android 沒有 /tmp 目錄,因此運行的時候會報錯,因此咱們把這個目錄修改成 /data 目錄,修改後的代碼以下:

 

1 #if IPERF_HOST

2     char template[] = "/tmp/iperf3.XXXXXX";

3 #else

4     char template[] = "/data/iperf3.XXXXXX";

5 #endif

 

ps: 不知是否平臺差別,測試data目錄不行,我本身用/sdcard/iperf3.xxxxxx測試ok

 

接下來把 src/config.h.in 重命名爲 src/config.h:

 

>$ mv src/config.h.in src/config.h

 

 

最後一步,刪掉 src/t_uuid.c、src/t_timer.c 和 src/t_units.c 三個文件,不然會出現 main() 函數衝突的錯誤。

固然,若是在 Android.mk 中經過 LOCAL_SRC_FILES 變量來指定每一個要編譯的源文件,再從中排除掉這三個文件也是能夠的。不過這樣作寫的內容比較羅嗦,乾脆把它們仨刪掉,直接用 LOCAL_SRC_FILES := $(call all-c-files-under, src) 自動包含 src 目錄下全部的 .c 文件。

 

>$ rm src/t_uuid.c src/t_timer.c src/t_units.c 

 

 

mm 編譯後會生成兩個文件,分別是 arm 版和 x86 版的可執行程序。

 

>$ mm

Install: out/host/linux-x86/bin/iperf_x86

Install: out/target/product/msm8909go/system/xbin/iperf

 

 

記錄一個遇到的坑:

 

一開始編譯的時候報這樣一個錯誤:

 

error: unused parameter 'argc' [-Werror,-Wunused-parameter]

main() 函數的 argc 參數沒有使用,通常來講報個警告就能夠了,爲何直接報成錯誤了呢?

後來仔細研究了生成的編譯命令發現裏面帶了 -Werror 參數,這個參數會將 warning 轉換爲 error,強制要求程序編譯期間不能出現警告。

爲了解決這個問題,只需在 Android.mk 中指定 -Wno-error 參數便可:

 

LOCAL_CFLAGS := -Wno-error

 

 

iperf 工具的使用很簡單,網上有不少教程,這裏只給出幾個示例。

 

啓動服務端:

 

># iperf -s

-s 參數表示以服務端形式啓動。

網上有些文章說若是使用 UDP 協議須要,指定 -u 參數。但經實測後發現,我使用的這個版本,服務端無需指定 -u 就能夠支持 TCP 和 UDP 兩種協議。

 

啓動客戶端:

 

./iperf_x86 -c 172.16.61.90 -u -t 600 -b 16M

-c 表示啓動客戶端,後面跟服務端的 IP 地址。

-u 表示使用 UDP 協議,不加此參數使用 TCP 協議。

-t 表示持續執行多少秒的測試,默認10秒。

-b 表示發送的數據包大小,TCP 默認使用最大帶寬,UDP 默認1Mbits。

 

TCP 協議適合用來測試最大帶寬,UDP 協議適合用來測試丟包率、網絡抖動等狀況。

原文出處:https://www.cnblogs.com/mengdao/p/11338766.html

相關文章
相關標籤/搜索