# iperf3_embedded **Repository Path**: sqqdfny/iperf3_embedded ## Basic Information - **Project Name**: iperf3_embedded - **Description**: iperf3 clinet + FreeRTOS + lwip - **Primary Language**: C - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-17 - **Last Updated**: 2026-06-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # iperf3-embedded **iperf3 client for embedded systems (FreeRTOS + lwIP)** 标准 [iperf3](https://github.com/esnet/iperf) 协议兼容的嵌入式客户端。支持 TCP/UDP、正向/反向吞吐量测试、带宽限制,适用于资源受限的 MCU/SoC 平台。 > ⚠️ **注意**:本项目代码全部由 DeepSeek 生成。 ## 特性 - 完整的 iperf3 协议客户端(esnet/iperf3 兼容) - TCP 吞吐量测试(正向 / 反向) - UDP 吞吐量测试(正向 / 反向),带带宽 pacing - 标准 JSON 参数交换 + cookie 握手 - 可选的 DNS 解析(基于 lwIP netdb) - 平台抽象层 — 仅两个函数需用户实现 ## 依赖 | 组件 | 说明 | |--------|--------------------------------| | RTOS | FreeRTOS(task、delay、yield) | | TCP/IP | lwIP BSD socket API | | DNS | lwIP netdb(可选,需 `LWIP_DNS`) | ## 集成 1. 将 `iperf3_embedded.h` 和 `iperf3_embedded.c` 加入工程 2. 实现两个平台抽象函数(见下方示例) 3. 可选:定义日志宏覆盖默认行为 ### 平台抽象 使用者必须提供两个函数: ```c #include "iperf3_embedded.h" /* 微秒级单调计数器 — 示例:用 FreeRTOS tick + 硬件定时器实现 */ uint64_t iperf3_platform_get_time_us(void) { /* 典型做法:读取一个 32 位硬件 μs 定时器 */ return (uint64_t)cpu_get_us_timer(); } /* 微秒级忙等待 — 仅用于亚毫秒延迟,毫秒级以上由 vTaskDelay 处理 */ void iperf3_platform_delay_us(uint32_t us) { uint64_t start = iperf3_platform_get_time_us(); while ((iperf3_platform_get_time_us() - start) < us) { /* busy-wait */ } } ``` ### 可选宏覆盖 在包含头文件之前定义以下宏,可替换默认输出行为: ```c #define IPERF3_PRINTF(fmt, ...) my_console_printf(fmt, ##__VA_ARGS__) #define IPERF3_LOG_ERR(fmt, ...) my_log_error("[iperf3] " fmt, ##__VA_ARGS__) #define IPERF3_LOG_WARN(fmt, ...) my_log_warn("[iperf3] " fmt, ##__VA_ARGS__) #define IPERF3_LOG_INFO(fmt, ...) my_log_info("[iperf3] " fmt, ##__VA_ARGS__) #define IPERF3_IOCTLSOCKET lwip_ioctl /* 部分 lwIP 移植需覆盖 */ ``` ## 使用示例 ### TCP 上行测试(默认 10 秒) ```c #include "iperf3_embedded.h" void run_tcp_test(void) { iperf3_client_cfg_t cfg = {0}; cfg.dest_ip = inet_addr("192.168.1.100"); cfg.port = 5201; cfg.time_sec = 10; cfg.interval_sec = 1; /* udp = 0, reverse = 0 (default TCP forward) */ iperf3_client_start(&cfg); /* 等待测试完成(或轮询 iperf3_client_is_running()) */ while (iperf3_client_is_running()) { vTaskDelay(pdMS_TO_TICKS(500)); } printf("Test finished.\r\n"); } ``` 典型输出: ``` iperf3: cookie=iperf3-embedded.1234.5678 iperf3: control connected Interval Bandwidth 0- 1 sec 5.23 Mbits/sec 1- 2 sec 5.18 Mbits/sec ... 9-10 sec 5.30 Mbits/sec Server report: 5.25 Mbits/sec (6562500 bytes in 10 sec) iperf3 done: total 5.25 Mbits/sec (6562500 bytes in 10 sec) ``` ### TCP 下行测试(反向) ```c iperf3_client_cfg_t cfg = {0}; cfg.dest_ip = inet_addr("192.168.1.100"); cfg.port = 5201; cfg.time_sec = 30; cfg.interval_sec = 1; cfg.reverse = 1; /* 服务器发 → 客户端收 */ iperf3_client_start(&cfg); ``` ### UDP 上行测试(5 Mbps 限速) ```c iperf3_client_cfg_t cfg = {0}; cfg.dest_ip = inet_addr("192.168.1.100"); cfg.port = 5201; cfg.time_sec = 10; cfg.interval_sec = 1; cfg.udp = 1; cfg.bw_limit_kbps = 5000; /* 5 Mbps */ iperf3_client_start(&cfg); ``` ### UDP 下行测试 + 自定义端口 ```c iperf3_client_cfg_t cfg = {0}; cfg.dest_ip = inet_addr("10.0.0.1"); cfg.port = 5201; cfg.time_sec = 15; cfg.interval_sec = 1; cfg.udp = 1; cfg.reverse = 1; iperf3_client_start(&cfg); ``` ### 使用 DNS 主机名(需 `LWIP_DNS`) ```c iperf3_client_cfg_t cfg = {0}; /* dest_ip 将被 DNS 结果覆盖 */ cfg.port = 5201; cfg.time_sec = 10; cfg.interval_sec = 1; iperf3_client_start_host(&cfg, "iperf.example.com"); ``` ### 中途停止测试 ```c /* 在另一个任务或中断中调用 */ iperf3_client_stop(); ``` ## API 参考 | 函数 | 说明 | |------|------| | `iperf3_client_start(cfg)` | 启动测试(创建 FreeRTOS 任务) | | `iperf3_client_stop()` | 停止正在运行的测试(最多等待 5 秒) | | `iperf3_client_is_running()` | 查询是否有测试正在运行 | | `iperf3_client_start_host(cfg, host)` | 通过 DNS 解析后启动(需 `LWIP_DNS`) | ### iperf3_client_cfg_t | 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `dest_ip` | `uint32_t` | — | 服务器 IP(网络字节序),用 `inet_addr()` 设置 | | `port` | `uint16_t` | `5201` | 服务器端口 | | `time_sec` | `uint32_t` | `10` | 测试时长(秒) | | `interval_sec` | `uint32_t` | `1` | 报告间隔(秒) | | `bw_limit_kbps` | `int` | `0` | 带宽限制(Kbps),`0` = 不限速(仅 UDP) | | `udp` | `uint8_t :1` | `0` | `1` = UDP,`0` = TCP | | `reverse` | `uint8_t :1` | `0` | `1` = 反向(服务器发送数据) | ### 可配置宏 | 宏 | 默认值 | 说明 | |----|--------|------| | `IPERF3_TCP_PORT` | `5201` | 默认端口 | | `IPERF3_DEFAULT_TIME` | `10` | 默认测试时长(秒) | | `IPERF3_TCP_BUF_SIZE` | `4096` | TCP 发送 / 接收缓冲区大小 | | `IPERF3_UDP_BUF_SIZE` | `1460` | UDP 数据报大小(避免分片) | | `IPERF3_TASK_PRIORITY` | `4` | 工作任务的 FreeRTOS 优先级 | | `IPERF3_TASK_STACK` | `4096` | 工作任务的栈大小(字节) | | `IPERF3_STOP_TIMEOUT_MS` | `5000` | 停止等待超时(毫秒) | | `IPERF3_SOCKET_TIMEOUT_S` | `2` | Socket 接收超时(秒) | ## 与标准 iperf3 服务器的兼容性 本客户端已通过以下标准 iperf3 服务器验证: ```bash # Linux / macOS 上启动标准 iperf3 服务器 iperf3 -s # 或指定端口 iperf3 -s -p 5201 ``` 协议兼容 [esnet/iperf3](https://github.com/esnet/iperf) 3.x 版本。 ## License MIT License — 详见 [LICENSE](LICENSE) 或源文件头部。