QProcess调用外部ping程序实现网络状态检测

时间:2021-09-30 15:22:11

QProcess调用外部ping程序实现网络状态检测

上代码:

/*
    作者:侯文斌
    E-mail:houwenbin1986@gmail.com
    注:请尊重原作者劳动成果,仅供学习使用,请勿盗用,违者必究!
*/
#ifndef SHELLPROCESS_H
#define SHELLPROCESS_H

#include <QStringList>
#include <QThread>
#include <QProcess>

//命令行工具类
class ShellProcess : public QThread
{
    Q_OBJECT
public:
    explicit ShellProcess(QObject *parent = 0);
    QStringList getIpRange();
public:
    static bool isAlive(QString ip, int port, int timeout = 1000);
signals:
    void commandSuccess(QString ip);
    void commandFailed(QString ip);
public slots:
    void setIpRange(QStringList ipRange);
    void readResult();
    void startedThread();
protected:
    void run();
private:
    void bindEvent();
private:
    QStringList ipRange;
    QProcess* m_process;
};

#endif // SHELLPROCESS_H


/*
    作者:侯文斌
    E-mail:houwenbin1986@gmail.com
    注:请尊重原作者劳动成果,仅供学习使用,请勿盗用,违者必究!
*/
#include "shellprocess.h"
#include <QtCore>
#include <QTcpSocket>
#include <QUdpSocket>

#define USE_PARSE_RESULT //使用解析返回内容方式

ShellProcess::ShellProcess(QObject *parent)
    : QThread(parent)
{
    m_process = new QProcess(this);
    this->bindEvent();
}

void ShellProcess::bindEvent()
{
    connect( this, SIGNAL(started()), this, SLOT(startedThread()) );
    connect( m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readResult()) );
}

QStringList ShellProcess::getIpRange()
{
    return this->ipRange;
}

void ShellProcess::setIpRange(QStringList ipRange)
{
    this->ipRange = ipRange;
}

void ShellProcess::startedThread()
{
#ifndef USE_PARSE_RESULT
    return ;
#endif

    QString ip;
    foreach( ip, ipRange )
    {
#ifdef Q_OS_WIN
        QString strArg = "ping -n 1 -i 2 "+ ip;
        m_process->start(strArg);//异步,才可以看到输出
        //m_process->execute(strArg);//同步,直接打印了
#else
        QStringList argstrList;
        argstrList << "-c 1" << "-t 2" << ip;
        m_process->start("ping", argstrList);//异步,才可以看到输出
        //m_process->execute("ping", argstrList);//同步,直接打印了
#endif
    }

}

void ShellProcess::run()
{
#ifdef USE_PARSE_RESULT
    return ;//结束线程
#endif

    QString ip;
    foreach( ip, ipRange )
    {
        qDebug() << "ping " + ip;
        //qDebug()<<"判断"<<ip<<"mysql在线与否:"<<isAlive(ip, 3306, 100);
        int exitCode = 0;
#ifdef Q_OS_WIN
        //启动一个ping进程,然后等待该进程结束。
        QString strArg = "ping " + ip + " -n 1 -i 2";
        exitCode = QProcess::execute(strArg);
#else
        exitCode = QProcess::execute("ping", QStringList() << "-c 1" << "-t 2" << ip);
#endif
        if ( 0 == exitCode ) {
            // it's alive
            qDebug() << "shell ping " + ip + " success";
            emit commandSuccess(ip);
        } else {
            qDebug() << "shell ping " + ip + " failed";
            emit commandFailed(ip);
        }
    }

}

//解析Console打印内容
void ShellProcess::readResult()
{
    QProcess *ping = qobject_cast<QProcess *>(sender());
    if ( !ping )
        return;
    QTextCodec *codec = QTextCodec::codecForName("GBK");//指定QString的编码方式
    QString res = codec->toUnicode( ping->readAllStandardOutput() );    
    QString ip = ping->arguments().last();
#ifdef Q_OS_WIN
    if ( !res.contains('%') )
        return;
    const int percent = res.mid(res.indexOf('('), res.indexOf(')')).section('%', 0, 0).remove('(').toInt();
    qDebug()<<res<<percent;
    if ( percent == 100 ) {
        qDebug() << ip << "host not found.";
        emit commandFailed(ip);
    } else {
        qDebug() << ip << "host found.";
        emit commandSuccess(ip);
    }
#else
    qDebug()<<res;
#endif
}

//判断IP地址及端口是否在线
bool ShellProcess::isAlive(QString ip, int port, int timeout)
{
    QTcpSocket tcpClient;
    tcpClient.abort();
    tcpClient.connectToHost(ip, port);
    //100毫秒没有连接上则判断不在线
    return tcpClient.waitForConnected(timeout);
}