获取 Linux 中可用的 WiFi 连接列表
Posted
技术标签:
【中文标题】获取 Linux 中可用的 WiFi 连接列表【英文标题】:Get list of available WiFi connections in Linux 【发布时间】:2020-07-30 02:07:23 【问题描述】:我正在尝试使用 Qt5 通过 D-Bus 消息获取 Fedora 31 Linux 中的 SSID 列表。
查了很多教程,还是不能用D-Bus交流,还是不明白接口、路径、服务的区别。借助文档帮助 (https://developer.gnome.org/NetworkManager/stable/spec.html) 和互联网,我写道:
QDBusInterface nm("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager.Device.Wireless", QDBusConnection::systemBus());
if(nm.isValid())
QDBusMessage msg = nm.call("GetAllAccessPoints");
但变量“msg”接收一个参数:
"No interface „org.freedesktop.NetworkManager.Device.Wireless” in object at path /org/freedesktop/NetworkManager"
如何连接到 D-Bus?
【问题讨论】:
不是一个真正的答案,但您是否考虑使用 networkmanager-qt:api.kde.org/frameworks/networkmanager-qt/html/index.html 以我的经验,它比直接使用 dbus 接口更不挑剔 【参考方案1】:您的困惑是有道理的,因为该过程并不是很直观。基本上你需要做的是首先创建一个代表 NetworkManager 本身的 QDBusInterface。通过该对象,您需要获取网络接口列表,遍历它们,过滤掉 WiFi 接口,创建相应的 QDBusInterface,指示接口扫描可用网络,然后请求可见接入点列表.然后,您将获得每个接入点对象的 SSID 属性。这是一个简单的例子,它用普通的 Qt 演示了这个过程:
list_ssid.pro:
QT -= gui
QT += dbus
SOURCES += list_ssid.cpp
list_ssid.cpp:
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>
#include <QDebug>
#include <QThread>
int main(int argc, char **argv)
QCoreApplication app(argc, argv);
// get the interface to nm
QDBusInterface nm("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager",
"org.freedesktop.NetworkManager", QDBusConnection::systemBus());
if(!nm.isValid())
qFatal("Failed to connect to the system bus");
// get all devices
QDBusMessage msg = nm.call("GetDevices");
qDebug() << "GetDevices reply: " << msg << endl;
QDBusArgument arg = msg.arguments().at(0).value<QDBusArgument>();
if(arg.currentType() != QDBusArgument::ArrayType)
qFatal("Something went wrong with getting the device list");
QList<QDBusObjectPath> pathsLst = qdbus_cast<QList<QDBusObjectPath> >(arg);
foreach(QDBusObjectPath p, pathsLst)
qDebug() << "DEV PATH: " << p.path();
// creating an interface used to gather this devices properties
QDBusInterface device("org.freedesktop.NetworkManager", p.path(),
"org.freedesktop.NetworkManager.Device", QDBusConnection::systemBus());
// 2 is WiFi dev, see https://people.freedesktop.org/~lkundrak/nm-docs/nm-dbus-types.html#NMDeviceType
if (device.property("DeviceType").toInt() != 2)
continue;
// we got a wifi device, let's get an according dbus interface
QDBusInterface wifi_device("org.freedesktop.NetworkManager", p.path(),
"org.freedesktop.NetworkManager.Device.Wireless", QDBusConnection::systemBus());
// we need to call scan on the inteface prior to request the list of interfaces
QMap<QString, QVariant> argList;
QDBusMessage msg = wifi_device.call("RequestScan", argList);
QThread::sleep(2); // not the best solution, but here we just wait for the scan
// doing the actual call
msg = wifi_device.call("GetAllAccessPoints");
qDebug()<< "Answer for GetAllAccessPoints: " << msg << endl << endl;
// dig out the paths of the Access Point objects:
QDBusArgument ap_list_arg = msg.arguments().at(0).value<QDBusArgument>();
QList<QDBusObjectPath> ap_path_list = qdbus_cast<QList<QDBusObjectPath> >(ap_list_arg);
// and iterate through the list
foreach(QDBusObjectPath p ,ap_path_list)
// for each Access Point we create an interface
QDBusInterface ap_interface("org.freedesktop.NetworkManager", p.path(),
"org.freedesktop.NetworkManager.AccessPoint", QDBusConnection::systemBus());
// and getting the name of the SSID
qDebug() << "SSID: " << ap_interface.property("Ssid").toString();
return 0;
同样使用networkmanager-qt,为了比较:
CMakeLists.txt:
project(ssid_list LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED COMPONENTS
Core
Gui
Network
DBus
)
find_package(KF5NetworkManagerQt REQUIRED)
add_executable(ssid_list
ssid_list.cpp
)
target_link_libraries(ssid_list Qt5::Core Qt5::DBus Qt5::Network KF5::NetworkManagerQt)
ssid_list.cpp
#include <arpa/inet.h>
#include <QThread>
#include <NetworkManagerQt/Manager>
#include <NetworkManagerQt/Device>
#include <NetworkManagerQt/WirelessDevice>
#include <NetworkManagerQt/AccessPoint>
int main()
// getting all of the devices, and iterate through them
NetworkManager::Device::List list = NetworkManager::networkInterfaces();
Q_FOREACH (NetworkManager::Device::Ptr dev, list)
if(dev->type() != NM_DEVICE_TYPE_WIFI)
//skipping non-wifi interfaces
continue;
// creating a Wifi device with this object path
NetworkManager::WirelessDevice wifi_dev(dev->uni());
wifi_dev.requestScan();
QThread::sleep(2); // still not the best solution:w
//get the Object Path of all the visible access points
// and iterate through
foreach(QString ap_path, wifi_dev.accessPoints())
// creating an AccessPoint object with this path
NetworkManager::AccessPoint ap(ap_path);
// and finally get the SSID
qDebug() << "SSID:" << ap.ssid();
【讨论】:
你的回答给了我很多信息,我从中学到了很多。我发现了一个差异。 RequestScan 需要输入参数才能工作,而不是刷新网络不起作用。我已对您的答案进行了编辑。我重写了您的代码以使用类,现在尝试学习如何连接到信号。以上是关于获取 Linux 中可用的 WiFi 连接列表的主要内容,如果未能解决你的问题,请参考以下文章
Android 12 Wifi 开发(获取列表连接断开连接)