You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Lua应用与Shell脚本中高效使用wpa_supplicant管理WiFi连接

基于wpa_supplicant的WiFi连接管理优化方案

1. 用wpa_supplicant控制接口替代ping轮询,实时获取连接状态

原来靠定时ping公共DNS判断连接状态,不仅延迟高,还浪费系统资源。直接利用wpa_supplicant自带的wpa_cli工具,通过控制接口实时获取连接状态:

  • 启动wpa_supplicant时指定控制接口:wpa_supplicant -B -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -C /var/run/wpa_supplicant
  • 执行wpa_cli -i wlan0 status,解析输出中的wpa_state核心字段:
    • COMPLETED:已成功连接WiFi并获取IP
    • DISCONNECTED:未处于连接状态
    • ASSOCIATING/AUTHENTICATING:正在连接过程中
  • Lua代码直接调用该命令解析结果,无需依赖Shell脚本写文件,示例:
function get_wifi_connection_state()
    local handle = io.popen("wpa_cli -i wlan0 status 2>/dev/null")
    if not handle then return "DISCONNECTED" end
    local output = handle:read("*a")
    handle:close()
    local wpa_state = output:match("wpa_state=(%w+)")
    return wpa_state or "DISCONNECTED"
end

2. 合并WiFi配置文件,让wpa_supplicant自动管理连接优先级

原来每个SSID单独一个配置文件,管理繁琐且无法利用wpa_supplicant的自动选网能力:

  • 把所有已保存的WiFi配置合并到一个/etc/wpa_supplicant.conf文件,每个网络用network块定义:
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1

network={
    ssid="YourWiFi1"
    psk="yourpassword1"
    priority=10  # 数值越高,连接优先级越高
}

network={
    ssid="YourWiFi2"
    psk="yourpassword2"
    priority=5
}
  • 配置完成后,wpa_supplicant会自动扫描并尝试连接优先级最高的可用已知网络,无需Lua手动遍历选择

3. 优化重连逻辑,避免频繁重启wpa_supplicant

原来每次重连都kill并重启wpa_supplicant,会导致不必要的服务中断,改用wpa_cli的控制命令实现平滑切换:

  • 当需要切换网络时,先通过wpa_cli -i wlan0 list_networks获取所有已配置网络的ID
  • 用wpa_cli -i wlan0 select_network <network_id>指定连接目标网络
  • 仅当wpa_supplicant进程异常时,才执行重启操作
  • 修改原First_Connection_Wifi函数,去掉killall逻辑,改为调用wpa_cli命令:
function First_Connection_Wifi(mapargs)
    local current_state = get_wifi_connection_state()
    if current_state == "COMPLETED" then return end

    -- 获取扫描结果
    local scan_handle = io.popen("wpa_cli -i wlan0 scan_results 2>/dev/null")
    if not scan_handle then return end
    local scan_output = scan_handle:read("*a")
    scan_handle:close()

    -- 获取已配置网络列表
    local networks_handle = io.popen("wpa_cli -i wlan0 list_networks 2>/dev/null")
    if not networks_handle then return end
    local networks_output = networks_handle:read("*a")
    networks_handle:close()

    -- 匹配可用的已配置网络并触发连接
    for line in networks_output:gmatch("[^\n]+") do
        local id, ssid = line:match("(%d+)%s+([^%s]+)%s+.*")
        if id and ssid and scan_output:find(ssid, 1, true) then
            os.execute("wpa_cli -i wlan0 select_network " .. id .. " &")
            Tempo_Last_Check_Connection = gre.mstime() / 1000
            return
        end
    end
end

4. 优化WiFi扫描逻辑,减少资源消耗

原来固定10秒扫描一次,改为按需扫描降低资源占用:

  • 仅当连接断开时触发扫描,或者当当前连接信号强度低于阈值时(通过iwconfig wlan0获取信号强度)触发扫描
  • 用wpa_cli -i wlan0 scan触发扫描,扫描完成后用scan_results获取结果,避免直接调用iwlist

5. 简化连接状态判断逻辑

去掉原Lua代码中依赖/tmp/connesso文件的轮询逻辑,改用定时调用状态获取函数:

-- 替换原有的counter_500ms相关逻辑
if counter_500ms % 10 == 0 then
    local wpa_state = get_wifi_connection_state()
    if wpa_state == "COMPLETED" then
        print("connesso")
        Connesso_A_Internet = true
        Tempo_Last_Check_Connection = gre.mstime() / 1000
    else
        if Connesso_A_Internet then
            -- 之前已连接,现在断开,等待20秒后尝试重连
            if math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) >= 20 then
                Connesso_A_Internet = false
                First_Connection_Wifi(mapargs)
            end
        else
            -- 未连接,间隔20秒尝试重连
            if math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) >= 20 then
                First_Connection_Wifi(mapargs)
            end
        end
    end
end

内容的提问来源于stack exchange,提问作者Merlin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:53:18