QT检测电脑是否能够上网

         在程序涉及到联网时,总是需要检测网络状态。而最直接、有效的网络状态检测方法就是使用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解析成功后就会显示在线,实际上电脑并不能上网。(实测,在公司禁外网的情况下,检测状态仍为在线)

        纠结了这么久,个人认为最简单、直接的判断网络状态的方法是,通过QProcess系统调用ping指令,再根据执行结果是否包含特殊字符串来判断网络状态。但是ping指令执行完毕需要耗时几秒,这样会导致检测实时性不强。这就需要研究ping指令的具体用法了。

如下为windows中ping命令的用法:

其中 -n 为请求数,-w 为请求超时时间。为了更快获取网络状态结果,调整这两个参数即可。例如:

ping www.baidu.com -n 2 -w 500

其含义为向www.baidu.com请求两包数据,每包数据超时时间为500ms。系统调用这个命令,就能在1s内获取网络状态了。但是如果在主线程中直接调用该指令,会存在阻塞,导致界面卡顿。所以,建议通过线程来调用ping指令。

如下为自己写的示例程序,供大家参考,若有问题还请大佬多多指正:

network_detect.h

#ifndef NETWORK_DETECT_H
#define NETWORK_DETECT_H

#include <QProcess>
#include <QThread>

class network_detect : public QThread
{
    Q_OBJECT            //一定要加这个
public:
    network_detect();
    virtual void run();
    void stop();
signals:
    void send_network_connect_state(int state);

private:
    bool flagRunning;   //线程运行标志
    QProcess *network_process;
};

#endif // NETWORK_DETECT_H

network_detect.cpp

#include "network_detect.h"

network_detect::network_detect()
{
    flagRunning = true;
}

void network_detect::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 send_network_connect_state(1);  //在线
        }
        else
        {
            emit send_network_connect_state(0); //离线
        }
        sleep(1);  //加sleep降低CPU占用率
    }
}

void network_detect::stop()
{
    flagRunning = false;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "network_detect.h"    //包含头文件
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
public slots:
    void update_network_state(int state); //更新网络状态

private:
    Ui::Widget *ui;
    network_detect *detect_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);
    detect_thread = new network_detect();
    connect(detect_thread, SIGNAL(send_network_connect_state(int)), this, SLOT(update_network_state(int)));
    detect_thread->start(); //开启网络检测线程
}

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

void Widget::update_network_state(int state)
{
    if(state)
        ui->label->setText("在线");
    else
        ui->label->setText("离线");
}

 程序运行结果:

程序能够迅速检测网络状态,并显示出来,网络正常时,显示结果如下:

网络异常或拔掉网线后,最多2s内能检测到离线,如下所示:

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值