Linux下测试Wifi性能——4.Wifi性能测试脚本

发布于:2025-03-05 ⋅ 阅读:(33) ⋅ 点赞:(0)

一、前言

在当今数字化时代,无线网络的性能对我们的日常生活和工作至关重要。无论是家庭网络环境中的日常娱乐,还是企业办公场景下的高效协作,稳定且高速的 Wi-Fi 连接都是保障各项业务顺利开展的基础。然而,Wi-Fi 网络的性能会受到多种因素的影响,如信号强度、网络拥塞、设备兼容性等。为了准确评估 Wi-Fi 网络的性能,及时发现并解决潜在问题,进行全面且细致的网络测试显得尤为重要。

本脚本旨在提供一个自动化的 Wi-Fi 网络性能测试工具,通过集成 wpa_cliiwiperf3 和 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文件中