qt网络判断

qt中网络判断有三种方式:

1.调用系统提供的dbus接口:org.freedesktop.NetworkManager,存在缺点:在Linux环境返回的状态有问题,而且状态变化时反应很慢。

2.qt自己的库,缺点也是反应慢,不能及时捕捉告知网络状态的变化。

QNetworkConfigurationManager ×m_pNetCfgMgr = new QNetworkConfigurationManager(this);       //分配空间        //判断初始的网络状态
qDebug() << "------" << m_pNetCfgMgr->isOnline();

3.访问指定的服务器。

1)通过QHostInfo访问指定的服务器,缺点还是状态变化反应很慢(测试是切换系统的网络开关);

2)连接指定的服务器,因为有没有外网及网络状态好不好是要通过数据流进行判断,自己可以封装个类通过http请求指定的服务器,根据返回状态来判断情况;

    connect(m_Timer, &QTimer::timeout, this, [=] ()
    {
        NetworkConnectivityCheck networkCheck(this);
        int baiduStatus = -1;

        if (!networkCheck.m_isEnter)
            baiduStatus = networkCheck.getNetworkStatus(BaiduHostName);

        if (CheckNetworkState::NetworkNormal == baiduStatus)
        {
            qDebug() << "baidu is ok";
            return true;
        }

        int bingStatus = -1;

        if (!networkCheck.m_isEnter)
            bingStatus = networkCheck.getNetworkStatus(BingHostName);

        if ((CheckNetworkState::NetworkNormal == bingStatus)
                || (CheckNetworkState::NetworkConnectionTimeout == baiduStatus
                    && CheckNetworkState::NetworkConnectionTimeout == bingStatus)
                /*|| networkCheck.getNetWorkInterfaceStatus()*/)
        {
            qDebug() << "bing is ok";
            return true;
        }

        qDebug() << "Current local network exception.";
        return false;

    });

下面为自己封装的类:

#ifndef NETWORKCONNECTIVITYCHECK_H
#define NETWORKCONNECTIVITYCHECK_H

#include <QObject>
#include <QEventLoop>
#include <QNetworkReply>
#include <QNetworkAccessManager>

enum CheckNetworkState {
    NetworkNormal,
    NetworkConnectionTimeout,
    NoNetwork
};

class NetworkConnectivityCheck : public QObject
{
    Q_OBJECT
public:
    explicit NetworkConnectivityCheck(QObject *parent = nullptr);
    ~NetworkConnectivityCheck();
    int getNetworkStatus(QString url);
    bool getNetWorkInterfaceStatus();
    QEventLoop m_synchronous;
public slots:
    void quitEventLoop();

public:
    bool m_isEnter;

private:
    QNetworkAccessManager m_networkManager;
    QNetworkReply *m_reply;
};

#endif // NETWORKCONNECTIVITYCHECK_H
#include "networkconnectivitycheck.h"

#include <QScopedPointer>
#include <QTimer>
#include <QNetworkInterface>

NetworkConnectivityCheck::NetworkConnectivityCheck(QObject *parent)
    : QObject(parent)
    , m_isEnter(false)
    , m_reply(nullptr)
{
    connect(&m_networkManager, &QNetworkAccessManager::finished, this,
            &NetworkConnectivityCheck::quitEventLoop);
}

NetworkConnectivityCheck::~NetworkConnectivityCheck()
{
    if (m_reply) {
        m_reply->abort();
        m_reply->deleteLater();
        m_reply = nullptr;
    }
    quitEventLoop();
}

int NetworkConnectivityCheck::getNetworkStatus(QString url)
{
    m_isEnter = true;
    m_reply = m_networkManager.get(QNetworkRequest(QUrl(url)));
    qDebug() << "Connecting to url:" << url;
    qDebug() << "QNetworkReply error:" << m_reply->errorString();

    QTimer *checkNetwork = new QTimer(this);
    bool isResult = false;
    int connectStatus = -1;
    checkNetwork->start(500);
    connect(checkNetwork, &QTimer::timeout, [&]() {
        if (!isResult) {
            checkNetwork->stop();
            qDebug() << "check network timeout 500ms.";
            connectStatus = CheckNetworkState::NetworkConnectionTimeout;
            quitEventLoop();
        }
    });

    m_synchronous.exec();

    if (CheckNetworkState::NetworkConnectionTimeout != connectStatus) {
        checkNetwork->stop();
        m_reply->close();

        if (m_reply->error() == QNetworkReply::NoError
                && m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
            qDebug() << "Connected to url:" << url << " success!";

            if (connectStatus == -1)
                connectStatus = CheckNetworkState::NetworkNormal;
        } else {
            qDebug() << "To connect url:" << url << " failed!";
            qDebug() << "QNetworkReply error:" << m_reply->errorString();
            if (connectStatus == -1)
                connectStatus = CheckNetworkState::NoNetwork;
        }
        isResult = true;
    }

    m_isEnter = false;
    return connectStatus;
}

bool NetworkConnectivityCheck::getNetWorkInterfaceStatus()
{
    QList<QNetworkInterface> networkList = QNetworkInterface::allInterfaces();
    bool isConnect = false;

    for (auto interface : networkList) {
        if (interface.isValid()) {
            //返回与此网络接口关联的标志。
            QNetworkInterface::InterfaceFlags flags = interface.flags();
            qDebug() << "flags: " << flags;
            qDebug() << "name: " << interface.name();

            if (flags.testFlag(QNetworkInterface::IsUp) && flags.testFlag(QNetworkInterface::IsRunning)
                    && !flags.testFlag(QNetworkInterface::IsLoopBack)) {
                isConnect = true;
                qDebug() << "get local network status is:" << isConnect;
            }
        }
    }

    return isConnect;
}

void NetworkConnectivityCheck::quitEventLoop()
{
    if (m_synchronous.isRunning())
        m_synchronous.quit();
}

4.底层封装网络判断接口。

总结:在和服务器进行数据交互时,优先判断网络情况(是否有外网,网络状况是否良好[是否存在弱网的环境]),然后判断服务器的联通和数据交互情况,如果是弱网就要考虑超时的情况,一般自己设置超时时间,屏蔽https的超时,具体还是根据实际的项目需要吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值