一、前言
在当今数字化时代,无线网络的性能对我们的日常生活和工作至关重要。无论是家庭网络环境中的日常娱乐,还是企业办公场景下的高效协作,稳定且高速的 Wi-Fi 连接都是保障各项业务顺利开展的基础。然而,Wi-Fi 网络的性能会受到多种因素的影响,如信号强度、网络拥塞、设备兼容性等。为了准确评估 Wi-Fi 网络的性能,及时发现并解决潜在问题,进行全面且细致的网络测试显得尤为重要。
本脚本旨在提供一个自动化的 Wi-Fi 网络性能测试工具,通过集成 wpa_cli
、iw
、iperf3
和 fping
等多种常用的网络工具,对 Wi-Fi 网络的信号强度、吞吐量、延迟和丢包率等关键指标进行周期性的测试,并将测试结果保存到 CSV 文件中。这样,用户可以方便地对测试数据进行分析和可视化处理,从而深入了解 Wi-Fi 网络的性能状况,为网络优化和故障排查提供有力依据。
二、脚本
#!/bin/bash
# 定义服务器 IP 地址和存储测试结果的 CSV 文件路径
SERVER_IP="172.16.20.92" //Iperf3 服务端的IP
file_path="wifi_test_results.csv"
#执行次数
PROCESS_COUNTS=1000 # 每次大概3s
# 写入 CSV 文件表头,去掉 fping 序号
echo "测试时间,测试序号,BSSID,SSID,信号强度(dBm),本地IP,本地端口,远程IP,远程端口,间隔,传输量(KBytes/s),比特率(Mbits/s),重传次数,拥塞窗口(KBytes),丢包率(%),fping字节数,fping延迟(ms)" > "$file_path"
# 测试当前连接的 Wi-Fi 信号强度
test_signal_strength() {
# 获取 wlan0 接口的 wpa_supplicant 状态信息
scan_output=$(wpa_cli -i wlan0 -p/var/run/wpa_supplicant status)
if [ $? -ne 0 ]; then
echo "wpa_cli 执行失败" >&2
return 1
fi
# 提取当前使用的 BSSID
bssid_using=$(echo "$scan_output" | grep "bssid=" | cut -d '=' -f 2)
# 扫描 wlan0 接口可用的 Wi-Fi 网络
scan_output=$(iw dev wlan0 scan)
if [ $? -ne 0 ]; then
echo "iw 执行失败" >&2
return 1
fi
bssid=""
ssid=""
signal=""
# 逐行解析扫描结果,提取所需信息
while IFS= read -r line; do
if [[ $line == "BSS"* ]]; then
bssid=${line:4:17}
elif [[ $bssid_using == "$bssid" && $line == *"signal"* ]]; then
signal=$(echo $line | awk '{print $2}')
elif [[ $bssid_using == "$bssid" && $line == *"SSID:"* ]]; then
ssid=${line#*SSID:}
decoded_ssid=$(printf "%b" "$ssid")
ssid=$decoded_ssid
break
fi
done <<< "$scan_output"
echo "$bssid,$ssid,$signal"
}
# 测试网络吞吐量
test_throughput() {
# 使用 iperf3 工具测试与服务器的网络吞吐量,测试时长为 1 秒
feedback=$(iperf3 -c $SERVER_IP -t 1 -p 5202)
if [ $? -ne 0 ]; then
echo "iperf3 执行失败" >&2
return 1
fi
# 定义关联数组存储吞吐量测试结果
declare -A data=(
[interval]="" [transfer]="" [bitrate]=""
[retr]="" [cwnd]=""
[local_ip]="" [local_port]=""
[remote_ip]="" [remote_port]=""
)
local line_num=0
# 逐行解析 iperf3 的输出结果
while IFS= read -r line; do
IFS=' ' read -ra parts <<< "$line"
((line_num++))
if [ $line_num -eq 2 ]; then
# 提取本地 IP、本地端口、远程 IP 和远程端口信息
data[local_ip]="${parts[3]}"
data[local_port]="${parts[5]}"
data[remote_ip]="${parts[8]}"
data[remote_port]="${parts[10]}"
elif [ $line_num -gt 3 ] && [ $line_num -lt 5 ]; then
# 提取间隔、传输量、比特率、重传次数和拥塞窗口信息
data[interval]="${parts[2]}"
data[transfer]="${parts[4]}"
data[bitrate]="${parts[6]}"
data[retr]="${parts[8]}"
data[cwnd]="${parts[9]}"
fi
done <<< "$feedback"
# 输出提取的信息,用逗号分隔
echo "${data[local_ip]},${data[local_port]},${data[remote_ip]},${data[remote_port]},"\
"${data[interval]},${data[transfer]},${data[bitrate]},"\
"${data[retr]},${data[cwnd]}"
}
# 测试网络延迟和丢包率
test_delay_loss() {
local test_time="$1"
local test_seq="$2"
local bssid="$3"
local ssid="$4"
local signal="$5"
local local_ip="$6"
local local_port="$7"
local remote_ip="$8"
local remote_port="$9"
local interval="${10}"
local transfer="${11}"
local bitrate="${12}"
local retr="${13}"
local cwnd="${14}"
# 使用 fping 工具向服务器发送 1 个大小为 512 字节的数据包进行延迟测试
ping_result=$(fping -c 1 -s 512 $SERVER_IP 2>&1)
# 检查输出中是否包含关键错误信息
if echo "$ping_result" | grep -q "unknown host" || echo "$ping_result" | grep -q "no route to host"; then
echo "fping 执行失败: $ping_result"
return 1
fi
# 提取丢包率信息
packet_loss=$(grep -oP '\d+(?=% loss)' <<< "$ping_result")
# 逐行解析 fping 的输出结果
while read -r line; do
if [[ $line =~ \[([0-9]+)\],\ ([0-9]+)\ bytes,\ ([0-9.]+)\ ms ]]; then
fping_bytes="${BASH_REMATCH[2]}"
fping_delay="${BASH_REMATCH[3]}"
# 将测试结果写入 CSV 文件,去掉 fping 序号
printf "%s,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%d,%.2f\n" \
"$test_time" "$test_seq" "$bssid" "$ssid" "$signal" \
"$local_ip" "$local_port" "$remote_ip" "$remote_port" \
"$interval" "$transfer" "$bitrate" "$retr" "$cwnd" \
"${packet_loss:-N/A}" \
"$fping_bytes" "$fping_delay" >> "$file_path"
fi
done <<< "$(grep "\[" <<< "$ping_result")"
}
# 主测试函数,协调各个测试步骤
wifi_test() {
for ((i = 1; i <= $PROCESS_COUNTS; i++)); do
# 获取当前时间
current_time=$(date +"%Y-%m-%d %H:%M:%S")
# 测试信号强度
signal_info=$(test_signal_strength)
if [ $? -ne 0 ]; then
continue
fi
# 解析信号强度测试结果
IFS=',' read -r bssid ssid signal <<< "$signal_info"
# 测试吞吐量
throughput_info=$(test_throughput)
if [ $? -ne 0 ]; then
continue
fi
# 解析吞吐量测试结果
IFS=',' read -r local_ip local_port remote_ip remote_port interval transfer bitrate retr cwnd <<< "$throughput_info"
# 测试延迟和丢包率
test_delay_loss "$current_time" "$i" "$bssid" "$ssid" "$signal" \
"$local_ip" "$local_port" "$remote_ip" "$remote_port" \
"$interval" "$transfer" "$bitrate" "$retr" "$cwnd"
done
echo "测试完成,结果已保存至 $file_path"
}
# 调用主测试函数开始测试
wifi_test
三、使用方法
1.将脚本保存为一个 .sh
文件,例如 wifi_test.sh
,并赋予执行权限:
chmod +x wifi_test.sh
2.运行脚本
sudo ./wifi_test.sh
3.脚本将会自动将测试结果放到脚本目录下的wifi_test_results.csv文件中