尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TCP/UDP性能测试工具实战:iperf3吞吐、丢包与协议栈调优避坑指南

TCP/UDP性能测试工具实战:iperf3吞吐、丢包与协议栈调优避坑指南 简介TCP_UDP_PerformanceTest 是一款面向网络编程开发者与系统运维人员的传输层协议性能测试工具用于对比 TCP 与 UDP 在真实网络环境下的吞吐量、延迟与丢包率表现帮助判断高并发低延迟场景下应选用哪种协议。资源包共 5 个文件约 79KB包含可执行主程序、封装底层通信逻辑的 dll 库、记录服务器地址与端口等运行参数的 config 配置、存储测试结果或参数的 xml 文件以及授权用的 sn 文件结构紧凑、开箱即用。用户可自定义发送数据量、发送速率与测试时长模拟不同负载条件观察 TCP 的可靠重传与 UDP 的轻量快速之间的实际差异。目前已有 1639 人学习下载适合需要评估协议选型、优化网络服务性能的读者参考实践。1. TCP_UDP_PerformanceTest 测试工具为什么你测出来的带宽总是对不上同一个千兆交换机两台机器之间iperf3跑 TCP 能到 940 Mbps换成 UDP 却怎么调都上不去或者干脆丢包丢到 30% 以上——这种场景我见过太多次。问题往往不在网卡也不在交换机而在于测试方法本身TCP 有拥塞控制和重传兜底UDP 没有两者的测试逻辑、参数含义、结果解读方式完全不同。TCP_UDP_PerformanceTest 测试工具要解决的就是让你在同一套框架下分别对 TCP 和 UDP 做可复现的吞吐、时延、丢包测试而不是拿一个数字到处套。这篇文章面向需要做网络性能验证的开发和运维你可能在调优tcp协议栈参数、验证udp协议栈的转发能力、排查tcp连接建立慢的问题或者只是想知道自己写的 socket 程序到底能跑多快。我会从测试模型讲起落到具体命令和参数再把踩过的坑摊开说。读完你至少能做到知道该测什么、怎么测、结果怎么读、哪里容易翻车。2. 先把测试模型立住TCP 和 UDP 到底该测什么2.1 两种协议的性能指标根本不是一回事很多人做性能测试的第一反应是“跑个带宽看看”但 TCP 和 UDP 的“带宽”含义不同。TCP 的吞吐量受拥塞窗口、往返时延、丢包率共同影响你测到的数字是协议栈在特定网络条件下协商出来的结果不是链路的上限。UDP 则是“发多少是多少”发送端可以一直灌接收端丢不丢、丢多少完全看中间设备和缓冲区。所以测试目标要分开定TCP 关注稳定吞吐量、连接建立时间、重传率、窗口变化。适合验证tcp标定原理相关的参数调优效果比如netsh interface tcp show global里看到的窗口缩放、ECN 状态。UDP 关注极限发送速率、丢包率、时延抖动、乱序比例。适合验证udp端口测试、udp探测场景下的链路质量。我一般会先明确一个问题你是要验证“这条链路最好能跑多少”还是“业务在真实条件下能跑多少”。前者用 UDP 打流逼近上限后者用 TCP 模拟真实连接行为。两者不能互相替代。2.2 测试拓扑和最小可复现环境不管用什么工具拓扑要先固定下来。最常见的两种直连测试两台机器网卡直连或者通过一台交换机。这种环境变量最少适合做基线。注意关闭防火墙、关闭省电模式、确认网卡协商速率。跨设备测试经过路由器、防火墙、NAT。这种环境更接近真实但变量多需要逐段排查。最小环境建议角色配置要求说明发送端千兆及以上网卡CPU 不低于 4 核避免 CPU 成为瓶颈接收端同上缓冲区调大接收窗口决定 UDP 丢包率中间设备关闭 QoS 或确认策略限速策略会直接污染结果操作系统Linux 或 Windows 均可命令略有差异提示测试前用ethtool确认网卡实际协商速率不要看标称值。我遇到过网线老化导致协商到 100 Mbps测了半天以为是软件问题。2.3 工具选型iperf3 为主自研脚本补位iperf3是TCP_UDP_PerformanceTest场景下最通用的选择支持 TCP 和 UDP 两种模式参数清晰结果可解析。常见做法是TCP 测试iperf3 -c server -t 30 -P 4UDP 测试iperf3 -c server -u -b 1G -t 30但iperf3有局限它测的是应用层吞吐不直接暴露协议栈内部指标。如果你需要看tcp dup ack机制触发情况、tcp三次握手耗时分布就得配合tcpdump或ss命令。自研脚本的价值在于可以定制测试逻辑比如模拟java tcp客户端重连场景下的连接风暴。我一般会先用iperf3跑基线再用脚本做针对性验证。两者结果对不上时优先信抓包。3. 用 iperf3 跑通 TCP 和 UDP 的最小命令集3.1 服务端和客户端的启动顺序与参数先在一台机器上启动服务端# 服务端监听 5201 端口绑定所有地址 iperf3 -s -p 5201 # 如果需要长期运行并输出日志 iperf3 -s -p 5201 --logfile /var/log/iperf3.log -D-s表示服务端模式-p指定端口-D是后台运行。服务端本身不需要太多参数但要注意防火墙放行。客户端 TCP 测试# TCP 测试持续 30 秒4 条并发流输出间隔 1 秒 iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4 -i 1 # 反向测试服务端发送客户端接收 iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4 -R-c是客户端模式-t是持续时间-P是并发流数量-i是报告间隔-R反转方向。并发流数量很关键单条 TCP 流在长肥管道上可能跑不满带宽-P 4或-P 8能更好压满链路。客户端 UDP 测试# UDP 测试目标带宽 1Gbps持续 30 秒包长 1400 iperf3 -c 192.168.1.100 -p 5201 -u -b 1G -t 30 -l 1400 -i 1-u切换 UDP 模式-b指定目标带宽-l指定包长。UDP 模式下-b是必须关注的参数设得太低测不出上限设得太高丢包率飙升。我一般从链路速率的 80% 开始试逐步往上加。3.2 结果里哪些数字真正值得看TCP 测试输出里重点看三行Sender/Receiver 的 Bitrate两者差距大说明接收端有瓶颈。Retr重传次数。非零就要查丢包原因。Cwnd拥塞窗口。如果一直上不去说明 RTT 或丢包限制了吞吐。UDP 测试输出里重点看Jitter时延抖动。实时业务对这个敏感。Lost/Total丢包率。超过 1% 就要警惕。发送端和接收端的带宽差差多少就是丢了多少。# 解析 iperf3 JSON 输出提取关键指标 iperf3 -c 192.168.1.100 -p 5201 -t 10 -J result.json # 用 jq 提取 TCP 重传和吞吐 jq .end.sum_sent.retransmits, .end.sum_received.bits_per_second result.json-J输出 JSON 格式方便脚本化。jq是解析 JSON 的常用工具上面命令分别取重传次数和接收端比特率。做自动化测试时这个组合比解析文本输出可靠得多。3.3 参数怎么调从默认值到针对性配置iperf3的默认参数适合快速验证但做性能测试需要针对性调整参数默认值建议调整适用场景-P14~8TCP 多流压满链路-lTCP 自适应 / UDP 1460UDP 设 1400 或 1200避免分片-bUDP 1Mbps从 80% 链路速率起UDP 极限测试-w系统默认256K 或 1M高带宽长时延链路-t10 秒30~60 秒稳定状态测量-w是 TCP 窗口大小在长肥管道上必须调大否则单流吞吐上不去。UDP 没有窗口概念但接收端缓冲区大小会影响丢包率这个要在系统层面调不是iperf3参数。注意UDP 测试时-b设成0表示不限速但实际会受 CPU 和网卡限制。不要用这个值做精确测量。4. 自研脚本补位抓包验证和协议栈指标采集4.1 用 Python 写一个最小 TCP/UDP 测试客户端iperf3覆盖不到的场景比如模拟特定连接模式、采集握手耗时就需要自己写。下面是一个最小 TCP 客户端记录连接建立时间和吞吐import socket import time def tcp_test(host, port, duration10): # 记录三次握手耗时 start time.time() sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) handshake_ms (time.time() - start) * 1000 print(fTCP handshake: {handshake_ms:.2f} ms) # 持续发送数据统计吞吐 payload bx * 1400 sent_bytes 0 end_time time.time() duration while time.time() end_time: try: n sock.send(payload) sent_bytes n except socket.error as e: print(fSend error: {e}) break elapsed duration print(fThroughput: {sent_bytes * 8 / elapsed / 1e6:.2f} Mbps) sock.close() tcp_test(192.168.1.100, 5201)这段代码做了两件事用time.time()夹住connect()调用测握手耗时然后循环send()统计发送字节数。payload设为 1400 字节是为了避免 IP 分片。实际使用时接收端也要有对应程序消费数据否则发送缓冲区满了会阻塞。UDP 版本更简单但要注意sendto()不保证送达import socket import time def udp_test(host, port, duration10, rate_mbps100): sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) payload bx * 1400 interval 1400 * 8 / (rate_mbps * 1e6) # 每个包的理论间隔 sent 0 end_time time.time() duration while time.time() end_time: sock.sendto(payload, (host, port)) sent 1 time.sleep(interval) # 简单限速 print(fSent {sent} packets, {sent * 1400 * 8 / duration / 1e6:.2f} Mbps) sock.close() udp_test(192.168.1.100, 5201)interval是按目标速率算出的发包间隔time.sleep()做粗粒度限速。这种方式精度不高但足够验证基本连通性和大致速率。要精确限速得用令牌桶或SO_TXTIME。4.2 用 tcpdump 和 ss 看协议栈内部状态脚本测的是应用层协议栈内部要靠系统工具# 抓取 TCP 握手和重传 tcpdump -i eth0 -nn tcp port 5201 and (tcp[tcpflags] (tcp-syn|tcp-ack) ! 0) # 查看当前 TCP 连接状态和窗口 ss -tin state established ( dport :5201 or sport :5201 ) # 统计重传和 dup ack netstat -s | grep -E retrans|duptcpdump的过滤表达式里tcp[tcpflags]用来匹配标志位tcp-syn和tcp-ack组合能抓到握手包。ss -tin输出里retrans字段直接显示重传次数cwnd显示拥塞窗口。netstat -s是全局统计适合看趋势。这些数据配合iperf3结果能定位大部分性能问题。比如iperf3显示重传高ss看到cwnd上不去基本就是链路丢包导致拥塞控制保守。4.3 自动化测试的串联方式单次测试说明不了问题需要多轮次、多参数组合。我一般用 shell 脚本串联#!/bin/bash # 多轮 TCP 测试输出 CSV for p in 1 2 4 8; do for i in $(seq 1 3); do result$(iperf3 -c 192.168.1.100 -p 5201 -t 10 -P $p -J) bw$(echo $result | jq .end.sum_received.bits_per_second) retr$(echo $result | jq .end.sum_sent.retransmits) echo $p,$i,$bw,$retr tcp_result.csv done done外层循环并发流数量内层循环重复次数每次提取带宽和重传写入 CSV。这样跑完能看出并发流和吞吐的关系以及结果的稳定性。UDP 版本类似把-u -b加上提取丢包率字段。提示自动化测试前先手动跑一轮确认环境正常否则脚本跑完发现全是异常值浪费时间。5. 避坑指南TCP_UDP_PerformanceTest 最常见的 5 个翻车点5.1 现象UDP 丢包率极高但链路看起来没问题原因接收端 socket 缓冲区太小或者接收程序处理不过来。UDP 没有流控发得快收得慢就直接丢。解决调大接收缓冲区Linux 下用sysctl -w net.core.rmem_max26214400程序里用setsockopt(SO_RCVBUF)。同时确认接收程序不是单线程阻塞处理。5.2 现象TCP 吞吐远低于预期但重传为 0原因单条流的拥塞窗口受 RTT 限制带宽时延积大的链路上单流跑不满。或者发送端 CPU 是瓶颈。解决增加并发流-P调大窗口-w检查发送端 CPU 使用率。用top看iperf3进程是否跑满一个核。5.3 现象测试结果每次差异很大无法复现原因中间设备有动态限速、其他流量干扰、或者网卡省电模式导致降频。解决固定测试时间窗口关闭网卡省电ethtool -s eth0 wol d只是关唤醒省电要查驱动参数在交换机上确认没有 QoS 策略。多跑几轮取中位数。5.4 现象UDP 测试显示发送 1Gbps接收只有 300Mbps原因中间设备限速、接收端丢包、或者发送端统计的是“尝试发送”而非“成功发送”。解决在接收端同时抓包统计实际到达包数对比iperf3接收端报告。如果抓包数对得上接收端报告说明丢在中间对不上说明接收端程序有问题。5.5 现象TCP 连接建立慢但吞吐正常原因DNS 解析慢、SYN 重传、或者tcp三次握手过程中有安全设备拦截。解决用tcpdump抓握手包看时间戳确认 SYN、SYN-ACK、ACK 的间隔。如果 SYN-ACK 来得慢查中间设备如果 ACK 发得慢查客户端协议栈。6. 进阶把测试结果变成可对比的基线数据单次测试的数字没有意义有意义的是基线。我的习惯是每套环境第一次测试时固定参数跑 5 轮取中位数和标准差存成基线文件。后续任何变更——换网卡、调内核参数、改应用配置——都跟基线对比。具体做法# 生成基线TCP 4 流30 秒5 轮 for i in $(seq 1 5); do iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4 -J | \ jq -r [.end.sum_received.bits_per_second, .end.sum_sent.retransmits] | csv \ baseline_tcp.csv done # 计算中位数和标准差 awk -F, {sum$1; vals[NR]$1} END { nasort(vals); median(n%2)?vals[(n1)/2]:(vals[n/2]vals[n/21])/2; for(i1;in;i){sq(vals[i]-sum/n)^2} printf Median: %.2f Mbps, StdDev: %.2f\n, median, sqrt(sq/n) } baseline_tcp.csvjq -r输出 CSV 格式awk计算中位数和标准差。中位数比平均值更能反映典型值标准差说明稳定性。如果标准差超过中位数的 10%说明测试环境不够干净结果不可信。UDP 基线同理但重点看丢包率和抖动的分布。我一般会把不同-b值下的丢包率画成曲线找到“丢包率开始明显上升”的拐点这个拐点就是实际可用带宽。注意基线不是一次性的。网络设备固件升级、内核版本变更、甚至机房温度变化都可能影响结果。定期重跑基线才能发现漂移。这套方法我用了几年最大的教训是不要相信单次测试的数字也不要相信没有抓包验证的结论。有一次排查一个“TCP 吞吐上不去”的问题iperf3显示重传为 0差点去查应用层结果tcpdump抓到大量 dup ack才发现是中间设备乱序导致的。工具给的是线索不是答案。希望帮到你。本文还有配套的精品资源点击获取
返回列表