最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux下實(shí)時(shí)獲取WiFi與熱點(diǎn)狀態(tài)的方法詳解

 更新時(shí)間:2025年08月08日 10:41:42   作者:極地星光  
在智能設(shè)備開發(fā)中,網(wǎng)絡(luò)狀態(tài)感知是基礎(chǔ)而關(guān)鍵的功能,本文將手把手教你用Qt在Linux環(huán)境下實(shí)現(xiàn)熱點(diǎn)和無線網(wǎng)絡(luò)狀態(tài)的檢測(cè),需要的朋友可以參考下

一、引言:為什么需要網(wǎng)絡(luò)狀態(tài)檢測(cè)?

1.1 典型應(yīng)用場(chǎng)景

在物聯(lián)網(wǎng)和智能設(shè)備開發(fā)中,網(wǎng)絡(luò)狀態(tài)檢測(cè)是基礎(chǔ)而關(guān)鍵的功能。想象以下場(chǎng)景:

  • 智能家居:當(dāng)家庭WiFi斷開時(shí),智能音箱自動(dòng)開啟熱點(diǎn)模式,讓用戶通過手機(jī)直連配置
  • 工業(yè)設(shè)備:生產(chǎn)線設(shè)備在檢測(cè)到網(wǎng)絡(luò)異常時(shí),自動(dòng)記錄狀態(tài)并開啟維護(hù)通道
  • 移動(dòng)終端:平板電腦在不同網(wǎng)絡(luò)環(huán)境下自動(dòng)調(diào)整同步策略,節(jié)省電量

1.2 技術(shù)實(shí)現(xiàn)目標(biāo)

實(shí)現(xiàn)以下核心功能:

功能描述技術(shù)指標(biāo)
WiFi連接檢測(cè)判斷設(shè)備是否連接到無線網(wǎng)絡(luò)響應(yīng)時(shí)間<1s
WiFi名稱獲取獲取當(dāng)前連接的無線網(wǎng)絡(luò)SSID支持特殊字符
熱點(diǎn)狀態(tài)檢測(cè)判斷設(shè)備是否處于熱點(diǎn)模式準(zhǔn)確率100%
熱點(diǎn)名稱獲取獲取設(shè)備熱點(diǎn)的SSID多編碼支持

1.3 技術(shù)原理概述

Linux系統(tǒng)通過NetworkManager服務(wù)管理網(wǎng)絡(luò)連接,提供了豐富的命令行工具:

  • iwgetid:查詢無線接口連接狀態(tài)
  • nmcli:NetworkManager的命令行接口
  • hostapd:熱點(diǎn)管理服務(wù)

Qt的QProcess類可以無縫調(diào)用這些系統(tǒng)命令,并通過解析輸出來獲取網(wǎng)絡(luò)狀態(tài)信息。

二、核心思路:結(jié)合Qt與Linux命令

2.1 技術(shù)架構(gòu)設(shè)計(jì)

2.2 關(guān)鍵命令分析

檢測(cè)WiFi連接狀態(tài)

# 返回當(dāng)前連接的SSID(無連接則返回空)
iwgetid -r

# 示例輸出:
# MyHomeWiFi

檢測(cè)熱點(diǎn)狀態(tài)

# 查看活動(dòng)連接中的熱點(diǎn)
nmcli connection show --active | grep wifi | grep ap

# 查看hostapd進(jìn)程
pgrep hostapd

獲取熱點(diǎn)名稱

# 通過nmcli獲取
nmcli device wifi show | grep SSID

# 通過hostapd配置獲取
grep ssid= /etc/hostapd/hostapd.conf

2.3 性能考量

  • 命令執(zhí)行時(shí)間:各命令在樹莓派4上的平均執(zhí)行時(shí)間
    • iwgetid:50-100ms
    • nmcli:200-300ms
    • pgrep:10-20ms
  • 優(yōu)化策略
    • 緩存結(jié)果,減少命令調(diào)用
    • 異步執(zhí)行,避免阻塞UI
    • 合理設(shè)置檢測(cè)間隔(建議1-5秒)

三、詳細(xì)實(shí)現(xiàn):

3.1 核心類實(shí)現(xiàn)

NetworkTool.h

#ifndef NETWORKTOOL_H
#define NETWORKTOOL_H

#include <QObject>
#include <QProcess>
#include <QTimer>

class NetworkTool : public QObject
{
    Q_OBJECT
public:
    explicit NetworkTool(QObject *parent = nullptr);
    
    // 基礎(chǔ)檢測(cè)功能
    Q_INVOKABLE bool isWifiConnected();
    Q_INVOKABLE QString wifiName();
    Q_INVOKABLE bool isHotspotActive();
    Q_INVOKABLE QString hotspotName();
    
    // 高級(jí)功能
    Q_INVOKABLE void startAutoRefresh(int interval = 3000);
    Q_INVOKABLE void stopAutoRefresh();
    
signals:
    void wifiStatusChanged(bool connected, const QString &name);
    void hotspotStatusChanged(bool active, const QString &name);
    
private slots:
    void refreshStatus();
    
private:
    QString executeCommand(const QString &cmd, const QStringList &args = {});
    QString parseWifiName(const QString &output);
    QString parseHotspotName(const QString &output);
    
    QTimer m_refreshTimer;
    bool m_lastWifiState = false;
    QString m_lastWifiName;
    bool m_lastHotspotState = false;
    QString m_lastHotspotName;
};

#endif // NETWORKTOOL_H

NetworkTool.cpp

#include "NetworkTool.h"
#include <QDebug>
#include <QFile>

NetworkTool::NetworkTool(QObject *parent) : QObject(parent)
{
    m_refreshTimer.setSingleShot(false);
    connect(&m_refreshTimer, &QTimer::timeout, this, &NetworkTool::refreshStatus);
}

bool NetworkTool::isWifiConnected()
{
    return !wifiName().isEmpty();
}

QString NetworkTool::wifiName()
{
    QString output = executeCommand("iwgetid", {"-r"});
    return parseWifiName(output);
}

bool NetworkTool::isHotspotActive()
{
    // 方法1:使用nmcli檢測(cè)
    QString output = executeCommand("nmcli", {"connection", "show", "--active"});
    if (output.contains("wifi") && output.contains("ap")) {
        return true;
    }
    
    // 方法2:檢測(cè)hostapd進(jìn)程
    output = executeCommand("pgrep", {"hostapd"});
    return !output.isEmpty();
}

QString NetworkTool::hotspotName()
{
    // 嘗試通過nmcli獲取
    QString output = executeCommand("nmcli", {"device", "wifi", "show"});
    QString name = parseHotspotName(output);
    if (!name.isEmpty()) return name;
    
    // 回退到讀取hostapd配置
    QFile config("/etc/hostapd/hostapd.conf");
    if (config.open(QIODevice::ReadOnly)) {
        while (!config.atEnd()) {
            QByteArray line = config.readLine().trimmed();
            if (line.startsWith("ssid=")) {
                return QString::fromUtf8(line.mid(5));
            }
        }
    }
    
    return "Unknown";
}

void NetworkTool::startAutoRefresh(int interval)
{
    m_refreshTimer.start(interval);
}

void NetworkTool::stopAutoRefresh()
{
    m_refreshTimer.stop();
}

void NetworkTool::refreshStatus()
{
    // 獲取當(dāng)前狀態(tài)
    bool wifiConnected = isWifiConnected();
    QString currentWifiName = wifiName();
    bool hotspotActive = isHotspotActive();
    QString currentHotspotName = hotspotName();
    
    // 檢查狀態(tài)變化
    if (wifiConnected != m_lastWifiState || currentWifiName != m_lastWifiName) {
        m_lastWifiState = wifiConnected;
        m_lastWifiName = currentWifiName;
        emit wifiStatusChanged(wifiConnected, currentWifiName);
    }
    
    if (hotspotActive != m_lastHotspotState || currentHotspotName != m_lastHotspotName) {
        m_lastHotspotState = hotspotActive;
        m_lastHotspotName = currentHotspotName;
        emit hotspotStatusChanged(hotspotActive, currentHotspotName);
    }
}

QString NetworkTool::executeCommand(const QString &cmd, const QStringList &args)
{
    QProcess process;
    process.start(cmd, args);
    if (!process.waitForFinished(1000)) {
        qWarning() << "Command timeout:" << cmd << args;
        return "";
    }
    return QString::fromUtf8(process.readAllStandardOutput()).trimmed();
}

QString NetworkTool::parseWifiName(const QString &output)
{
    // iwgetid -r 直接返回SSID或空
    return output;
}

QString NetworkTool::parseHotspotName(const QString &output)
{
    // 解析nmcli輸出中的SSID
    QStringList lines = output.split('\n');
    for (const QString &line : lines) {
        if (line.trimmed().startsWith("SSID:")) {
            return line.mid(5).trimmed();
        }
    }
    return "";
}

3.2 UI集成示例

Qt Widgets版本

// MainWindow.h
#include <QMainWindow>
#include "NetworkTool.h"

namespace Ui { class MainWindow; }

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onWifiStatusChanged(bool connected, const QString &name);
    void onHotspotStatusChanged(bool active, const QString &name);

private:
    Ui::MainWindow *ui;
    NetworkTool m_networkTool;
};

// MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    // 連接信號(hào)
    connect(&m_networkTool, &NetworkTool::wifiStatusChanged,
            this, &MainWindow::onWifiStatusChanged);
    connect(&m_networkTool, &NetworkTool::hotspotStatusChanged,
            this, &MainWindow::onHotspotStatusChanged);
    
    // 啟動(dòng)自動(dòng)刷新
    m_networkTool.startAutoRefresh();
    
    // 初始化狀態(tài)
    onWifiStatusChanged(m_networkTool.isWifiConnected(), 
                       m_networkTool.wifiName());
    onHotspotStatusChanged(m_networkTool.isHotspotActive(),
                         m_networkTool.hotspotName());
}

void MainWindow::onWifiStatusChanged(bool connected, const QString &name)
{
    ui->wifiStatusLabel->setText(connected ? "已連接" : "未連接");
    ui->wifiNameLabel->setText(connected ? name : "N/A");
    ui->wifiIcon->setPixmap(QPixmap(connected ? ":/icons/wifi-on.png" 
                                             : ":/icons/wifi-off.png"));
}

void MainWindow::onHotspotStatusChanged(bool active, const QString &name)
{
    ui->hotspotStatusLabel->setText(active ? "已開啟" : "未開啟");
    ui->hotspotNameLabel->setText(active ? name : "N/A");
    ui->hotspotIcon->setPixmap(QPixmap(active ? ":/icons/hotspot-on.png"
                                            : ":/icons/hotspot-off.png"));
}

QML版本

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
    id: window
    width: 400
    height: 300
    visible: true
    title: "網(wǎng)絡(luò)狀態(tài)監(jiān)測(cè)"
    
    NetworkTool {
        id: networkTool
        onWifiStatusChanged: {
            wifiStatusText.text = connected ? "已連接" : "未連接"
            wifiNameText.text = name || "N/A"
        }
        onHotspotStatusChanged: {
            hotspotStatusText.text = active ? "已開啟" : "未開啟"
            hotspotNameText.text = name || "N/A"
        }
        Component.onCompleted: startAutoRefresh()
    }
    
    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 15
        
        GroupBox {
            title: "WiFi狀態(tài)"
            Layout.fillWidth: true
            
            GridLayout {
                columns: 2
                width: parent.width
                
                Label { text: "狀態(tài):" }
                Label { id: wifiStatusText }
                
                Label { text: "名稱:" }
                Label { id: wifiNameText }
            }
        }
        
        GroupBox {
            title: "熱點(diǎn)狀態(tài)"
            Layout.fillWidth: true
            
            GridLayout {
                columns: 2
                width: parent.width
                
                Label { text: "狀態(tài):" }
                Label { id: hotspotStatusText }
                
                Label { text: "名稱:" }
                Label { id: hotspotNameText }
            }
        }
        
        Button {
            text: "手動(dòng)刷新"
            Layout.alignment: Qt.AlignHCenter
            onClicked: networkTool.refreshStatus()
        }
    }
}

四、注意事項(xiàng):避坑指南

4.1 權(quán)限問題解決

常見權(quán)限錯(cuò)誤

  • nmcli報(bào)錯(cuò):“權(quán)限不足”
  • iwgetid無法獲取信息

解決方案

Polkit規(guī)則配置(推薦):

sudo nano /etc/polkit-1/rules.d/10-network-info.rules

添加內(nèi)容:

polkit.addRule(function(action, subject) {
    if (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 &&
        subject.isInGroup("users")) {
        return polkit.Result.YES;
    }
});

用戶組配置

sudo usermod -aG netdev,network $USER

sudo免密碼(開發(fā)測(cè)試用):

echo "$USER ALL=(ALL) NOPASSWD: /usr/bin/nmcli, /usr/bin/iwgetid" | sudo tee /etc/sudoers.d/network

4.2 系統(tǒng)兼容性處理

不同發(fā)行版適配

發(fā)行版檢測(cè)命令配置文件路徑
Ubuntu/Debiannmcli/iwgetid/etc/NetworkManager/
CentOS/RHELnmcli/iw/etc/sysconfig/network-scripts/
Arch Linuxiw/wpa_cli/etc/netctl/

兼容性代碼改進(jìn)

QString NetworkTool::wifiName()
{
    // 嘗試iwgetid
    QString output = executeCommand("iwgetid", {"-r"});
    if (!output.isEmpty()) return output;
    
    // 回退到iw命令
    output = executeCommand("iw", {"dev", "wlan0", "link"});
    QRegularExpression regex("SSID: (.+)");
    QRegularExpressionMatch match = regex.match(output);
    if (match.hasMatch()) {
        return match.captured(1);
    }
    
    return "";
}

4.3 性能優(yōu)化進(jìn)階

優(yōu)化策略

  • 命令執(zhí)行優(yōu)化
// 異步執(zhí)行命令
void NetworkTool::executeCommandAsync(
    const QString &cmd,
    const QStringList &args,
    std::function<void(QString)> callback)
{
    QProcess *process = new QProcess(this);
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
        [=](int exitCode, QProcess::ExitStatus exitStatus){
            if (exitStatus == QProcess::NormalExit) {
                callback(QString::fromUtf8(process->readAllStandardOutput()));
            }
            process->deleteLater();
        });
    process->start(cmd, args);
}
  • 智能刷新機(jī)制
void NetworkTool::refreshStatus()
{
    // 僅當(dāng)界面可見時(shí)刷新
    if (!m_windowVisible) return;
    
    // 根據(jù)網(wǎng)絡(luò)狀態(tài)動(dòng)態(tài)調(diào)整間隔
    if (m_lastWifiState) {
        m_refreshTimer.setInterval(5000); // 連接狀態(tài)穩(wěn)定時(shí)降低頻率
    } else {
        m_refreshTimer.setInterval(1000); // 未連接時(shí)提高檢測(cè)頻率
    }
    // ...原有刷新邏輯...
}
  • 結(jié)果緩存
struct NetworkCache {
    bool wifiConnected;
    QString wifiName;
    bool hotspotActive;
    QString hotspotName;
    QDateTime lastUpdated;
};

NetworkCache m_cache;

void NetworkTool::refreshCache()
{
    if (m_cache.lastUpdated.secsTo(QDateTime::currentDateTime()) < 2) {
        return; // 2秒內(nèi)不重復(fù)更新
    }
    // ...更新緩存...
}

五、擴(kuò)展

智能網(wǎng)絡(luò)切換

void autoSwitchNetwork()
{
    if (!m_networkTool.isWifiConnected() && 
        !m_networkTool.isHotspotActive()) {
        // WiFi斷開且熱點(diǎn)未開啟時(shí),自動(dòng)開啟熱點(diǎn)
        QProcess::startDetached("nmcli", {
            "device", "wifi", "hotspot", 
            "ssid", "RescueHotspot",
            "password", "12345678"
        });
    }
}

網(wǎng)絡(luò)質(zhì)量監(jiān)測(cè)

int getWifiSignalStrength()
{
    QString output = executeCommand("iwconfig", {"wlan0"});
    QRegularExpression regex("Signal level=(-?\\d+) dBm");
    QRegularExpressionMatch match = regex.match(output);
    if (match.hasMatch()) {
        return match.captured(1).toInt();
    }
    return 0;
}

歷史狀態(tài)記錄

void logNetworkStatus()
{
    QFile logFile("network_status.log");
    if (logFile.open(QIODevice::Append)) {
        QString log = QString("%1|%2|%3|%4\n")
            .arg(QDateTime::currentDateTime().toString())
            .arg(m_lastWifiState)
            .arg(m_lastWifiName)
            .arg(m_lastHotspotState);
        logFile.write(log.toUtf8());
    }
}

以上就是Linux下實(shí)時(shí)獲取WiFi與熱點(diǎn)狀態(tài)的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Linux獲取WiFi與熱點(diǎn)狀態(tài)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • centos8自定義目錄安裝nginx(教程詳解)

    centos8自定義目錄安裝nginx(教程詳解)

    這篇文章主要介紹了centos8自定義目錄安裝nginx的詳細(xì)教程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Linux體檢,了解你的Linux狀態(tài)(網(wǎng)絡(luò)IO,磁盤,CPU,內(nèi)存)

    Linux體檢,了解你的Linux狀態(tài)(網(wǎng)絡(luò)IO,磁盤,CPU,內(nèi)存)

    這篇文章主要介紹了為L(zhǎng)inux做個(gè)檢查,了解你的Linux的狀態(tài),學(xué)會(huì)查看linux各種狀態(tài),包括:網(wǎng)絡(luò)IO、磁盤、CPU、內(nèi)存等; 學(xué)會(huì)理解命令所代表的含義,能夠迅速發(fā)現(xiàn)集群存在的問題
    2021-08-08
  • Ubuntu環(huán)境下使用G++編譯CPP文件

    Ubuntu環(huán)境下使用G++編譯CPP文件

    今天小編就為大家分享一篇關(guān)于Ubuntu環(huán)境下使用G++編譯CPP文件,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Ubuntu報(bào)“無法解析域名cn.archive.ubuntu.com“問題解決辦法

    Ubuntu報(bào)“無法解析域名cn.archive.ubuntu.com“問題解決辦法

    在Ubuntu系統(tǒng)上使用sudo?apt?update命令更新時(shí)可能遇到“無法解析域名cn.archive.ubuntu.com”的問題,這通常是因?yàn)閏n.archive.ubuntu.com的鏡像資源不穩(wěn)定,為解決此問題,可以更換為穩(wěn)定性好、速度快的鏡像源,需要的朋友可以參考下
    2024-11-11
  • Hbase入門詳解

    Hbase入門詳解

    今天小編就為大家分享一篇關(guān)于Hbase入門詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Linux清理服務(wù)器磁盤空間的方法

    Linux清理服務(wù)器磁盤空間的方法

    本文介紹了清理服務(wù)器磁盤空間的方法,首先,使用命令分析磁盤狀態(tài),找出占用空間大的目錄和文件,然后將不需要的文件移至其他掛載點(diǎn)或刪除,最后,清理系統(tǒng)日志記錄,騰出更多空間,需要的朋友可以參考下
    2026-04-04
  • Linux文件系統(tǒng)掛載參數(shù)優(yōu)化指南

    Linux文件系統(tǒng)掛載參數(shù)優(yōu)化指南

    在Linux系統(tǒng)管理與性能調(diào)優(yōu)的世界里,文件系統(tǒng)的掛載參數(shù)往往被忽視,卻對(duì)系統(tǒng)整體性能、穩(wěn)定性和安全性有著深遠(yuǎn)影響,本文將深入探討Linux主流文件系統(tǒng)(ext4, XFS, Btrfs等)的掛載參數(shù)優(yōu)化策略,需要的朋友可以參考下
    2026-04-04
  • Linux 中刪除文本中的回車字符的方法

    Linux 中刪除文本中的回車字符的方法

    當(dāng)回車字符(Ctrl+M)讓你緊張時(shí),別擔(dān)心。有幾種簡(jiǎn)單的方法消除它們,感興趣的朋友跟隨腳本之家小編一起看看吧
    2019-09-09
  • Linux/Unix關(guān)于時(shí)間和時(shí)間戳的命令行

    Linux/Unix關(guān)于時(shí)間和時(shí)間戳的命令行

    這篇文章主要介紹了Linux/Unix關(guān)于時(shí)間和時(shí)間戳的命令行以及輸出的樣式區(qū)別,一起來學(xué)習(xí)下吧。
    2017-12-12
  • linux Bash腳本判別使用者的身份方法示例

    linux Bash腳本判別使用者的身份方法示例

    這篇文章主要介紹了linux Bash腳本判別使用者的身份方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01

最新評(píng)論

镇江市| 余干县| 大邑县| 彝良县| 西乌珠穆沁旗| 东平县| 南岸区| 五华县| 朝阳区| 青川县| 涡阳县| 曲周县| 格尔木市| 平山县| 石景山区| 常山县| 济南市| 兰州市| 那曲县| 苍山县| 邢台市| 永嘉县| 宜川县| 定南县| 湟中县| 小金县| 德化县| 无锡市| 黔东| 天峻县| 潢川县| 乡宁县| 嘉义县| 兴仁县| 邹城市| 西盟| 永嘉县| 广南县| 泰兴市| 钟山县| 柳林县|