- 在程序涉及到联网时,总是需要检测网络状态。而最直接有效的网络状态检测方法就是使用ping命令。我们通常判断网络是否通畅,会使用ping www.baidu.com之类的命令。 网上有许多判断网络状态的例子,比如:
QHostInfo::lookupHost("www.baidu.com",this,SLOT(onLookupHost(QHostInfo)));
void CommonParameter::onLookupHost(QHostInfo host)
{
if (host.error() != QHostInfo::NoError) {
qDebug() << "Lookup failed:" << host.errorString();
emit sigLookUpHostResult(false); //离线
}
else
emit sigLookUpHostResult(true); //在线
}
但是该方法,离线后需要一段时间才能判断出来。并且在DNS解析成功后就会显示在线,实际上电脑并不能上网。(实测,在公司禁外网的情况下,检测状态仍为在线)但是该方法,离线后需要一段时间才能判断出来。并且在DNS解析成功后就会显示在线,实际上电脑并不能上网。(实测,在公司禁外网的情况下,检测状态仍为在线)
如下为windows中ping命令的用法:
其中 -n 为请求数,-w 为请求超时时间。为了更快获取网络状态结果,调整这两个参数即可。例如:
ping www.baidu.com -n 2 -w 500
其含义为向www.baidu.com请求两包数据,每包数据超时时间为500ms。系统调用这个命令,就能在1s内获取网络状态了。但是如果在主线程中直接调用该指令,会存在阻塞,导致界面卡顿。所以,建议通过线程来调用ping指令。
如下为示例程序,供大家参考,若有问题还请大佬多多指正:
networkThread.h
#ifndef NETWORKTHREAD_H
#define NETWORKTHREAD_H
#include <QProcess>
#include <QThread>
class networkThread: public QThread
{
Q_OBJECT //一定要加这个
public:
networkThread();
virtual void run();
void stop();
signals:
void signalsNetwork_States(bool state);
private:
bool flagRunning; //线程运行标志
QProcess *network_process;
};
#endif // NETWORKTHREAD_H
networkThread.cpp
#include "networkThread.h"
networkThread::networkThread()
{
flagRunning = true;
}
void networkThread::run()
{
QString network_cmd = "ping www.baidu.com -n 2 -w 500";
QString result;
network_process = new QProcess(); //不要加this
while(flagRunning)
{
network_process->start(network_cmd); //调用ping 指令
network_process->waitForFinished(); //等待指令执行完毕
result = network_process->readAll(); //获取指令执行结果
if(result.contains(QString("TTL="))) //若包含TTL=字符串则认为网络在线
{
emit signalsNetwork_States(1); //在线
}
else
{
emit signalsNetwork_States(0); //离线
}
sleep(1); //加sleep降低CPU占用率
}
}
void networkThread::stop()
{
flagRunning = false;
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "networkThread.h" //包含头文件
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
void slot_updateNetwork(bool state); //更新网络状态
private:
Ui::Widget *ui;
networkThread *netWork_thread;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
netWork_thread= new networkThread();
connect(netWork_thread, SIGNAL(signalsNetwork_States(bool)), this, SLOT(slot_updateNetwork(bool)));
netWork_thread->start(); //开启网络检测线程
}
Widget::~Widget()
{
delete ui;
}
void Widget::slot_updateNetwork(bool state)
{
if(state)
ui->label->setText("在线");
else
ui->label->setText("离线");
}