Hands-On Mobile and Embedded Development with Qt 5 学习笔记 - QNetwork

在这里插入图片描述

QNetworkConfiguration 表示网络连接配置,例如到特定接入点的 Wi-Fi 连接,其服务集标识符 (SSID) 作为配置名称。

网络配置可以是以下类型之一:

QNetworkConfiguration::InternetAccessPoint:
这种类型是典型的接入点,例如 Wi-Fi 接入点 (AP),也可以代表以太网或移动网络。

QNetworkConfiguration::ServiceNetwork:
ServiceNetwork 类型是一组称为服务网络访问点 (SNAP) 的访问点。系统将根据成本、速度和可用性等标准确定最适合连接的服务网络。 QNetworkConfiguration::ServiceNetwork 类型的配置也可以在其子 QNetworkConfiguration::InternetAccessPoint 之间漫游。
QNetworkConfiguration::UserChoice:
这种类型可以代表用户首选的配置。它被诺基亚的 Maemo 和 Symbian 平台使用,系统可以在其中弹出一个对话框,要求用户选择最好的 AP。当前的承载后端都没有使用这种类型的 QNetworkConfiguration。
通常,我们需要知道承载的类型,也就是说,连接使用的是什么通信协议。让我们了解一下 BearerType。

QNetworkConfiguration::BearerType

这是一个枚举,指定 QNetworkConfiguration 的底层技术是什么,可以是以下之一:

BearerEthernet
BearerWLAN
Bearer2G
BearerCDMA2000
BearerWCDMA
BearerHSPA
BearerBluetooth
BearerWiMAX
BearerEVDO
BearerLTE
Bearer3G
Bearer4G
这可以通过调用 QNetworkConfiguration 对象的 bearerType() 函数来确定,如下所示:

QNetworkConfiguration 配置;您可以打开或连接。

QNetworkConfiguration config;
if (config.bearerType() == QNetworkConfiguration::Bearer4G)
    qWarning() << "Config is using 4G";

QNetworkConfiguration::StateFlags

StateFlags 是一个 OR’d ||,StateFlag 值的组合,如下所示:

Defined:系统已知但尚未配置
Discovered:已知并配置,可用于open()
Active:目前在线
具有 Active 标志的 QNetworkConfiguration 也将具有 Discovered 和 Defined 标志。 您可以通过执行以下操作来检查配置是否处于活动状态:

QNetworkConfiguration config;
if (config.testFlag(QNetworkConfiguration::Active))
    qWarning() << "Config is active";

网络配置管理器

QNetworkConfigurationManager 允许您获取系统的 QNetworkConfigurations,如下所示:

QNetworkConfigurationManager manager;
QNetworkConfiguration default = manager.defaultConfiguration();

在使用之前等待来自 QNetworkConfigurationManager 的 updateCompleted 信号总是明智的,以确保配置设置正确。
默认配置是系统定义为默认的配置。它的状态可能是 Active 或只是 Discovered。

如果需要简单判断系统当前是否在线,manager->isOnline();如果系统被认为在线,将返回 true。在线是指它通过网络连接到另一台设备,该网络可能是也可能不是互联网,并且可能会或可能不会正确路由。所以,它可以在线,但不能访问互联网。

您可能需要调用 updateConfigurations(),它会要求系统更新配置列表,然后您需要在继续之前监听 updateCompleted 信号。

您可以通过调用 allConfigurations() 获取系统已知的所有配置,或者使用 allConfigurations(QNetworkConfiguration::Discovered); 将其过滤为具有特定状态的配置。

在这种情况下,它返回已发现配置的列表。

CanStartAndStopInterfaces:系统允许用户启动和停止连接
DirectConnectionRouting:连接路由直接绑定到指定的设备接口
SystemSessionSupport:系统保持连接打开,直到所有会话都关闭
ApplicationLevelRoaming:应用程序可以控制漫游/迁移
ForcedRoaming:漫游/迁移时系统将重新连接
DataStatics:系统提供有关传输和接收数据的信息
NetworkSessionRequired:系统需要一个会话

NetworkSession 提供了一种启动和停止连接以及提供连接会话管理的方法。在使用 ServiceNetwork 类型的 QNetworkConfiguration 实例化 QNetworkSession 的情况下,它可以提供漫游功能。在大多数系统上,漫游将需要实际断开连接,然后连接新的接口和/或连接。在其他情况下,漫游可以是无缝的并且不会干扰用户的数据流。

如果 QNetworkConfigurationManager 的功能报告它支持 CanStartAndStopInterfaces,那么您使用 QNetworkSession 来 open()(连接)和 stop()(关闭)QNetworkConfigurations。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkSession>
#include <QNetworkConfigurationManager>
#include <QNetworkReply>

namespace Ui {
class MainWindow;
}

class MainWindow :  public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager *accessMan;
    //QNetworkConfiguration 表示网络连接配置,例如到特定接入点的 Wi-Fi 连接,其服务集标识符 (SSID) 作为配置名称。
    QNetworkConfigurationManager *configMan;
    QString stateToString(QNetworkSession::State state);
    void printCaps(QNetworkConfigurationManager::Capabilities);

private slots:
    void stateChanged(QNetworkSession::State state);
    void finished(QNetworkReply *reply);
    void opened();
    void updateCompleted();
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QNetworkConfiguration>
#include <QNetworkConfigurationManager>
#include <QNetworkSession>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QObject>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //QNAM 在后台发出网络请求时将使用 QNetworkSession。您可以使用 QNetworkSession 来监视连接,如下所示
    accessMan = new QNetworkAccessManager(this);
    QObject::connect(accessMan, &QNetworkAccessManager::finished,
                     this, &MainWindow::finished);
    qWarning() << "network accessible" << accessMan->networkAccessible();
    configMan = new QNetworkConfigurationManager(this);
    connect(configMan, &QNetworkConfigurationManager::updateCompleted,
            this, &MainWindow::updateCompleted);
	//如果需要简单判断系统当前是否在线,manager->isOnline();如果系统被认为在线,将返回 true。在线是指它通过网络连接到另一台设备,该网络可能是也可能不是互联网,并且可能会或可能不会正确路由。所以,它可以在线,但不能访问互联网。
    qWarning() << "isOnline?" << configMan->isOnline();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::stateChanged(QNetworkSession::State state)
{
    qDebug() << Q_FUNC_INFO << stateToString(state);
}

QString MainWindow::stateToString(QNetworkSession::State state)
{
    switch (state) {
    case QNetworkSession::NotAvailable:
        return QStringLiteral("NotAvailable");
        break;
    case QNetworkSession::Connected:
        return QStringLiteral("Connected");
        break;
    case QNetworkSession::Connecting:
        return QStringLiteral("Connecting");
        break;
    case QNetworkSession::Closing:
        return QStringLiteral("Closing");
        break;
    case QNetworkSession::Disconnected:
        return QStringLiteral("Disconnected");
        break;
    case QNetworkSession::Roaming:
        return QStringLiteral("NotAvailable");
        break;
    default:
        break;
    };
    return "Invalid";
}

void MainWindow::printCaps(QNetworkConfigurationManager::Capabilities caps)
{
    if (caps.testFlag(QNetworkConfigurationManager::CanStartAndStopInterfaces))
        qWarning() << "CanStartAndStopInterfaces";
    if (caps.testFlag(QNetworkConfigurationManager::DirectConnectionRouting))
        qWarning() << "DirectConnectionRouting";
    if (caps.testFlag(QNetworkConfigurationManager::SystemSessionSupport))
        qWarning() << "SystemSessionSupport";
    if (caps.testFlag(QNetworkConfigurationManager::ApplicationLevelRoaming))
        qWarning() << "ApplicationLevelRoaming";
    if (caps.testFlag(QNetworkConfigurationManager::ForcedRoaming))
        qWarning() << "ForcedRoaming";
    if (caps.testFlag(QNetworkConfigurationManager::DataStatistics))
        qWarning() << "DataStatistics";
    if (caps.testFlag(QNetworkConfigurationManager::NetworkSessionRequired))
        qWarning() << "NetworkSessionRequired";
    if (caps.testFlag(QNetworkConfigurationManager::CanStartAndStopInterfaces))
        qWarning() << "CanStartAndStopInterfaces";
}

void MainWindow::finished(QNetworkReply *reply)
{
    if (reply->error() == QNetworkReply::NoError)
        qWarning() << Q_FUNC_INFO;//<< reply->readAll();
    else
        qWarning() << Q_FUNC_INFO << reply->errorString();
}

void MainWindow::opened()
{
    qWarning() << Q_FUNC_INFO;
    QNetworkRequest request(QUrl("http://example.com"));

    accessMan->get(request);
}

void MainWindow::updateCompleted()
{
    qWarning() << "isOnline?" << configMan->isOnline();
    qWarning() << "network accessible" << accessMan->networkAccessible();

    printCaps(configMan->capabilities());

    QNetworkConfiguration configuration = accessMan->configuration();

    qWarning() << configuration.name() << configuration.state();
    qDebug() <<"activeConfiguration"<< accessMan->activeConfiguration().name();
    qDebug() <<"defaultConfiguration"<< configMan->defaultConfiguration().name();

    QNetworkSession *session = new QNetworkSession(configuration, this);

    qWarning() << stateToString(session->state());
    connect(session, &QNetworkSession::stateChanged, this, &MainWindow::stateChanged);
    connect(session, &QNetworkSession::opened, this, &MainWindow::opened);

    if (session->isOpen()) {
        opened();
    } else {
        qWarning() << "opening";
           session->open();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值