本篇总结
基于 W55MH32 实现 iperf3 以太网测速,实测 TCP 接收约 33.5Mbps、TCP 发送约 26.53Mbps、UDP 接收约 26.12Mbps、UDP 发送约 27.97Mbps。
🔑 KEIL MDK、UART调试、硬件TOE引擎、TCP、UDP、iperf3
硬件平台:本例程基于 W55MH32L-EVB 开发板运行。
采购推荐:点击前往 WIZnet 官方淘宝店铺 选购 W55MH32L-EVB
本示例演示如何使用 W55MH32 配合 iperf3 工具进行以太网测速,涵盖 TCP/UDP 收发速率测试全流程。通过配置网络参数、初始化 Socket 缓存、运行主循环监听连接,核心函数 start_iperf_test 完成数据高速收发与吞吐量统计,直观反映 W55MH32 嵌入式以太网设备的通信性能。
前置工具准备
开始本例程前,请确认以下工具已安装:
- WIZ UartTool V1.0:串口调试工具:点击下载
- iperf3:开源网络带宽测速工具,支持 TCP/UDP 协议:点击下载
iperf3 测试工具简介
iperf3 是跨平台、开源免费的专业网络性能测试工具,支持 TCP/UDP 协议,可精准测量带宽、丢包率等核心指标。通过简单命令行即可启动测试,支持 Windows、Linux 操作系统,可与 W55MH32 嵌入式芯片进行数据交互,为硬件验证、固件优化提供可靠量化数据。
- 双协议测试:支持 TCP、UDP 协议,精准测量带宽吞吐率
- 轻量跨平台:适配 Windows/Linux 及 ARM 嵌入式平台,命令行操作,无需复杂配置
- 开源可靠:基于 BSD 开源协议免费使用,测试结果贴合实际传输场景
测速流程
打开 iperf3 程序文件夹,在地址栏输入 cmd 打开命令行窗口,配置 W55MH32 端网络参数使其与 PC 处于同一网段,即可开始测试。影响速率的关键因素包括 MCU 主频、Socket 缓存大小和单次传输数据长度。
硬件连接与拓扑
请注意:
测试需要 PC 端和 W55MH32 处于同一网段。
- Micro USB 线连接 DEBUG USB 口到 PC(供电 + 调试串口)
- 网线连接开发板 RJ45 网口 到路由器 LAN 口
┌─────────────────────────────────┐
│ 路由器(DHCP Server) │
│ 192.168.1.1 │
└────┬──────────────────┬───────────┘
│ │
┌────┴──────┐ ┌────┴──────┐
│ W55MH32 │ │ PC │
│ iperf3 Srv│ │CMD iperf3 │
│ IP: DHCP │ │ IP: DHCP │
└───────────┘ └───────────┘
↑ ↑
DEBUG USB ──→ WIZ UartTool
网络拓扑:开发板与 PC 在同一局域网内,通过路由器互通
工程结构
工程位于 SDK 内 1.SDK\ModuleDemo\WZTOE\iperf3\,核心文件如下:
iperf3/
├── Project/
│ └── Project.uvprojx ← Keil 工程文件
└── USER/
├── main.c ← 网络初始化 + iperf3 主循环
├── iperf3.c ← iperf3 测速核心函数
└── iperf3.h
步骤1:设置 W55MH32 和电脑的基本网络参数
文件:USER/main.c — 配置网络地址信息,使 W55MH32 与 PC 处于同一网段内。
/* network information */
wiz_NetInfo default_net_info = {
.mac = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12}, /* User-defined MAC address */
.ip = {192, 168, 1, 30},
.gw = {192, 168, 1, 1},
.sn = {255, 255, 255, 0},
.dns = {8, 8, 8, 8},
.dhcp = 1
};
uint8_t ethernet_buf_tx[ETHERNET_BUF_MAX_SIZE] = {0};
uint8_t ethernet_buf_rx[ETHERNET_BUF_MAX_SIZE] = {0};
uint8_t dest_ip[4] = {192, 168, 1, 20};
uint16_t dest_port = 8080;
default_net_info 结构体定义了 MAC 地址、IP、网关、子网掩码、DNS 和 DHCP 模式。ethernet_buf_tx/rx 作为网络数据收发缓冲区。
步骤2:初始化 Socket 缓存
文件:USER/main.c — 为 Socket 0 和 Socket 1 各分配 8KB 收发缓存,供控制 Socket 和数据 Socket 使用。
uint8_t tx_size[_WIZCHIP_SOCK_NUM_] = {8, 8, 0, 0, 0, 0, 0, 0};
uint8_t rx_size[_WIZCHIP_SOCK_NUM_] = {8, 8, 0, 0, 0, 0, 0, 0};
数组索引对应 Socket 编号,值表示缓存大小等级(8 = 8KB)。Socket 0 作为控制 Socket,Socket 1 作为数据 Socket,总缓存不超过 W55MH32 的 32KB 限制。
如果你想自定义
- 增大缓存提升吞吐量 → 将 tx_size 和 rx_size 的值改大(如 16 = 16KB),但总缓存不超过 32KB
步骤3:主循环监听连接
文件:USER/main.c — 主循环通过状态机监听 TCP 连接,处理参数协商、流创建,并调用 start_iperf_test() 执行测速。
while (1)
{
stats_init(&stats, 1000);
socket_status = getSn_SR(SOCKET_CTRL);
if (socket_status == SOCK_ESTABLISHED)
{
handle_param_exchange(SOCKET_CTRL, &reverse, &udp);
handle_create_streams(SOCKET_CTRL, udp, remote_ip, &remote_port);
start_iperf_test(SOCKET_CTRL, SOCKET_DATA, &stats, reverse, udp, remote_ip, &remote_port);
close(SOCKET_DATA);
disconnect(SOCKET_CTRL);
}
else if (socket_status == SOCK_CLOSE_WAIT)
{
disconnect(SOCKET_CTRL);
}
else if (socket_status == SOCK_CLOSED)
{
socket(SOCKET_CTRL, Sn_MR_TCP, PORT_IPERF, Sn_MR_ND);
listen(SOCKET_CTRL);
printf("The iperf3 test is ready. Please enter the following command for testing:\r\n");
printf("TCP RX: iperf3 -c %d.%d.%d.%d -p 5007\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
printf("TCP TX: iperf3 -c %d.%d.%d.%d -p 5007 -R\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
printf("UDP RX: iperf3 -c %d.%d.%d.%d -p 5007 -u -b 100M -l 1460\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
printf("UDP TX: iperf3 -c %d.%d.%d.%d -p 5007 -u -b 100M -R\r\n",net_info.ip[0],net_info.ip[1],net_info.ip[2],net_info.ip[3]);
}
}
Socket 处于 SOCK_CLOSED 状态时打开 TCP Socket 并监听 5007 端口,串口打印四条测速命令。连接建立后协商参数并调用 start_iperf_test() 进行测速。
iperf3 命令参数说明
-c 指定目标 IP,-p 指定端口,-R 反向模式(W55MH32 发送数据),-u UDP 测试,-b 指定带宽,-l 指定数据包长度。
核心代码:start_iperf_test 测速函数
文件:USER/iperf3.c | 函数:start_iperf_test() — 接收前序协商的测试参数,通过独立的控制/数据 Socket 完成测速数据的高速收发,实时统计传输字节数、吞吐量等核心数据。
void start_iperf_test(uint8_t socket_ctrl, uint8_t socket_data, Stats *stats, bool reverse, bool udp, uint8_t *remote_ip, uint16_t *remote_port)
{
bool running = true;
uint8_t cmd = 0;
uint32_t pack_len = 0;
uint16_t sent_size, recv_size;
printf("[iperf] Starting data stream test...\n");
/* Start test */
cmd = TEST_START;
send(socket_ctrl, &cmd, 1);
/* Running test */
cmd = TEST_RUNNING;
send(socket_ctrl, &cmd, 1);
stats_start(stats);
while (running)
{
if (getSn_RX_RSR(SOCKET_CTRL) > 0)
{
recv(SOCKET_CTRL, &cmd, 1);
if (cmd == TEST_END)
{
printf("[iperf] TEST_END command received. Stopping test...\n");
running = false;
break;
}
}
if (reverse)
{
if(udp)
{
sent_size = sendto(socket_data, ethernet_buf_tx, ETHERNET_BUF_MAX_SIZE, remote_ip, *(remote_port));
}
else
{
sent_size = send(socket_data, ethernet_buf_tx, ETHERNET_BUF_MAX_SIZE / 2);
}
stats_add_bytes(stats, sent_size);
}
else
{
getsockopt(socket_data, SO_RECVBUF, &pack_len);
if (pack_len > 0)
{
if(udp)
{
recv_size = recvfrom(socket_data, (uint8_t *)ethernet_buf_rx, ETHERNET_BUF_MAX_SIZE, remote_ip, remote_port);
}
else
{
recv_size = recv(socket_data, (uint8_t *)ethernet_buf_rx, ETHERNET_BUF_MAX_SIZE);
}
stats_add_bytes(stats, recv_size);
}
else if (pack_len == 0)
{
stats_update(stats, false);
}
else
{
printf("[iperf] Error during data reception\n");
break;
}
}
stats_update(stats, false);
}
stats_stop(stats);
exchange_results(SOCKET_CTRL, stats);
}
函数通过控制 Socket 监听 TEST_END 指令,根据 reverse(发送/接收)和 udp(TCP/UDP)参数选择数据 Socket 的收发方式,实时统计传输字节数,最终通过 exchange_results() 将测速结果回传客户端。
测速注意事项
进行测速测试时,请务必关闭电脑防火墙,否则可能影响测试结果或导致连接失败。
运行验证
烧录例程运行后,首先进行 PHY 链路检测,然后打印网络地址信息,最后打印 iperf3 命令行。打开 WIZ UartTool V1.0,连接 DEBUG USB 对应 COM 口(115200 / 8N1),典型输出如下:
The iperf3 test is ready. Please enter the following command for testing:
TCP RX: iperf3 -c 192.168.1.30 -p 5007
TCP TX: iperf3 -c 192.168.1.30 -p 5007 -R
UDP RX: iperf3 -c 192.168.1.30 -p 5007 -u -b 100M -l 1460
UDP TX: iperf3 -c 192.168.1.30 -p 5007 -u -b 100M -R
打开 iperf3 程序文件夹,在地址栏输入 cmd 打开命令行窗口,依次执行四条测速命令,分别完成 TCP 接收、TCP 发送、UDP 接收、UDP 发送测试。
WIZ UartTool 串口输出 — iperf3 测速初始化(PHY 链路 + 网络地址 + iperf3 就绪)
| 测试项目 | 命令 | 实测速率 |
| TCP 接收 | iperf3 -c 192.168.1.30 -p 5007 | ~33.5 Mbps |
| TCP 发送 | iperf3 -c 192.168.1.30 -p 5007 -R | ~26.53 Mbps |
| UDP 接收 | iperf3 -c 192.168.1.30 -p 5007 -u -b 100M -l 1460 | ~26.12 Mbps |
| UDP 发送 | iperf3 -c 192.168.1.30 -p 5007 -u -b 100M -R | ~27.97 Mbps |
CMD iperf3 客户端 + WIZ UartTool 串口输出 — TCP 接收测试(~33.5 Mbps)
CMD iperf3 客户端(-R 反向)+ WIZ UartTool 串口输出 — TCP 发送测试(~26.53 Mbps)
CMD iperf3 客户端(-u -b 100M)+ WIZ UartTool 串口输出 — UDP 接收测试(~26.12 Mbps)
CMD iperf3 客户端(-u -b 100M -R -l 8192)+ WIZ UartTool 串口输出 — UDP 发送测试(~27.97 Mbps)常见问题
Q: 为什么测速时需要关闭防火墙
防火墙可能会拦截 iperf3 的网络连接请求或过滤测速数据包,导致连接失败或测试结果不准确。关闭防火墙可以确保 iperf3 与 W55MH32 之间的通信畅通无阻,获得真实的带宽测试数据。测试完成后可重新开启防火墙。
Q: 如何提升 W55MH32 的测速速率
影响速率的三个关键因素:一是 MCU 主频,主频越高数据处理越快;二是 Socket 缓存大小,例程中设置 tx_size 和 rx_size 为 8(即 8KB),增大缓存可提升单次吞吐量;三是单次传输数据长度,增大 ETHERNET_BUF_MAX_SIZE 可减少收发次数。同时确保 PHY 工作在 100Mbps 全双工模式。
Q: TCP 和 UDP 测速结果为什么不同
TCP 协议需要建立连接、确认应答、重传机制等,协议开销较大但保证数据可靠性;UDP 协议无连接、无确认,开销小但不保证可靠传输。实测中 TCP 接收 33.5Mbps 高于 UDP 接收 26.12Mbps,这与 W55MH32 硬件 TCP 卸载引擎(TOE)的加速特性有关,硬件加速 TCP 处理效率更高。
Q: iperf3 命令中的 -R 参数是什么含义
-R 参数表示反向模式(Reverse),即由服务端向客户端发送数据。不加 -R 时,W55MH32 作为服务端接收数据(RX 测试);加 -R 时,W55MH32 作为服务端发送数据(TX 测试)。通过 -R 参数可以分别测试设备的接收和发送速率。
Q: Socket 缓存大小如何配置
通过 tx_size 和 rx_size 数组配置每个 Socket 的收发缓存大小,数组索引对应 Socket 编号,值表示缓存大小等级(0=0KB, 1=1KB, 2=2KB, ..., 8=8KB, ..., 16=16KB)。例程中设置 Socket 0 和 Socket 1 各 8KB,其余为 0,总缓存不超过 W55MH32 的 32KB 限制。测速时分配较大缓存给控制 Socket 和数据 Socket。
总结
本文基于 W55MH32 配合 iperf3 工具实现了以太网测速:
- 工具选择:iperf3 是开源免费、跨平台的网络性能测试工具,支持 TCP/UDP 协议,适合嵌入式以太网设备性能评估
- 实现流程:配置网络参数 → 初始化 Socket 缓存 → 主循环监听 → start_iperf_test 核心测速函数收发数据并统计
- 速率影响因素:MCU 主频、Socket 缓存大小、单次传输数据长度是三大关键因素
- 实测结果:TCP 接收约 33.5Mbps、TCP 发送约 26.53Mbps、UDP 接收约 26.12Mbps、UDP 发送约 27.97Mbps
- 测试注意:测速前需关闭防火墙,确保电脑与 W55MH32 处于同一网段