Qt 之检测程序是否连外网
2021/4/11 14:27:28
本文主要是介绍Qt 之检测程序是否连外网,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
项目交互中,经常要用到websocket,http与服务器通信,但是网络情况又没法保证,网络可能一会是链接状态,一会是断开状态,所以需要有能力实时去检测网络状态;传统方法,或者要求行不高的情况下,大多采取程序中单独去个线程,去定时获取外网是否联通。但在商业项目中,尤其是toc的行业,这种网络检测一定要稳定、靠谱,不然直接会给商品大打折扣。
本项目,刚开始也是采用了传统的方法开个网络检测线程,但后来跟人沟通,这种方法不适合,比如在电脑端,如果10个程序都需要联网呢?难道需要10个app都要开线程去检测嘛。所以,网络检测应该时系统层面链路层的东西。
下面简单介绍下传统检测的两种方法,直接给代码了!
使用QNetworkAccessManager / post
.h
class NetLiveWorker : public QObject { Q_OBJECT public: explicit NetLiveWorker(QObject *parent = nullptr); ~NetLiveWorker(); Q_INVOKABLE bool getLive(){return m_isLive;} Q_INVOKABLE bool IsHostOnline(QString strHostName, int nTimeoutmSeconds = 2000); bool IsWebOk(); signals: void sig_netChanged(bool); public slots: void onTimeout(); private: bool m_isLive; bool m_isFirst; QNetworkAccessManager *pmanager; };
.cpp
NetLiveWorker::NetLiveWorker(QObject *parent) : QObject(parent) { m_isFirst = true; m_isLive = false; pmanager = new QNetworkAccessManager(this); } NetLiveWorker::~NetLiveWorker() { if(pmanager) delete pmanager; pmanager = NULL; } bool NetLiveWorker::IsWebOk() { //return IsHostOnline("110.242.68.4", 2000); return IsHostOnline("https://www.baidu.com/", 3000); } void NetLiveWorker::onTimeout() { bool islive = IsWebOk(); //qDebug()<<"Worker::onTimeout islive =" << islive << "m_islive=" << m_isLive; if(m_isLive != islive || m_isFirst) { emit sig_netChanged(islive); } m_isLive = islive; m_isFirst = false; //qDebug()<<"Worker::onTimeout get called from : "<<QThread::currentThreadId() << m_isLive; } bool NetLiveWorker::IsHostOnline(QString strHostName, int nTimeoutmSeconds) { QNetworkRequest request(strHostName); request.setRawHeader("Content-Type", "charset='utf-8'"); request.setRawHeader("Content-Type", "application/json"); QEventLoop eventloop; QTimer timer; timer.singleShot(nTimeoutmSeconds, &eventloop, SLOT(quit())); timer.start(); QNetworkReply* reply = pmanager->get(request); QMetaObject::Connection conRet = QObject::connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit())); Q_ASSERT(conRet); eventloop.exec(QEventLoop::ExcludeUserInputEvents); if (!timer.isActive()) { //超时,未知状态 QObject::disconnect(reply, SIGNAL(finished()), &eventloop, SLOT(quit())); reply->abort(); reply->deleteLater(); return false; } if (reply->error() != QNetworkReply::NoError) { //qDebug() << "error = " <<reply->error(); reply->abort(); reply->deleteLater(); return false; } bool bRes = reply->readAll().length() > 0; reply->abort(); reply->deleteLater(); return bRes; }
使用getlive方法即可拿到当前外网状态。
ping命令实现
.h
class NetworkDetect : public QThread { Q_OBJECT public: NetworkDetect(); virtual void run(); void stop(); signals: void sig_netStatusChanged(bool state); private: bool flagRunning; //线程运行标志 QProcess *network_process; };
.cpp
NetworkDetect::NetworkDetect() { flagRunning = true; } void NetworkDetect::run() { QString network_cmd = "ping www.baidu.com -w 500 -n 2"; QString result; network_process = new QProcess(); //不要加this while(flagRunning) { network_process->start(network_cmd); //调用ping 指令 network_process->waitForFinished(); //等待指令执行完毕 result = network_process->readAll(); //获取指令执行结果 //qDebug() << result; if(result.contains(QString("TTL=")) || result.contains(QString("ttl="))) //若包含TTL=字符串则认为网络在线 { emit sig_netStatusChanged(true); //在线 } else { emit sig_netStatusChanged(false); //离线 } sleep(1); //加sleep降低CPU占用率 } } void NetworkDetect::stop() { flagRunning = false; }
不同平台下ping命令的参数不一样,可通过 ping --help来参考
扩展
在某些嵌入式平台下,应该时系统层面通过回调函数来告诉你外网是否联通,有种wifi情况下,即使通知你链接成功了,也未必能通外网,还是需要你通过portalAuth机制来检测下。即拿到网络链路成功后,通过http或者ping方法确实是否能连外网。
Portal认证简介
Portal认证通常也称为Web认证,一般将Portal认证网站称为门户网站。用户上网时,必须在门户网站进行认证,只有认证通过后才可以使用网络资源。
用户可以主动访问已知的Portal认证网站,输入用户名和密码进行认证,这种开始Portal认证的方式称作主动认证。反之,如果用户试图通过HTTP访问其他外网,将被强制访问Portal认证网站,从而开始Portal认证过程,这种方式称作强制认证。
内置portal认证---------指的就是会话认证。
外置Portal认证
这篇关于Qt 之检测程序是否连外网的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南