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 
#include 
#include 
#include 

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 
#include 
#include 

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 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的超时,具体还是根据实际的项目需要吧。

你可能感兴趣的:(qt网络判断)