본문 바로가기

QT/QT 4.6.2

QProcess 클래스를 이용하여 Ping 명령 사용하기

QT에서 통신을 하기 전에 먼저 통신을 해야 하는 IP 주소와의 네트워크 상태를 알아 보기 위해

ping이라는 명령어를 사용하게 된다.

이 명령어는 명령프롬프트에서는 간단하게 ping xxx.xxx.xxx.xxx 로 상태를 확인 할 수 있는데, 

QT에서 이 ping 기능을 사용해야 될 것 같아, 자료를 찾아 보니, QProcess 클래스를 이용하여

이 명령어를 사용할 수 있다는 것을 알 수 있었다.

간단하게 소스를 보게 되면,

/*********************************************************************
                             TestPing.h
*********************************************************************/

#ifndef TESTPING_H
#define TESTPING_H

#include 
#include 
#include 
#include 
#include 


class PingProcess : public QWidget
{
  Q_OBJECT
public:
  PingProcess(QWidget* parent = 0);
  ~PingProcess();

public slots:
        void updateErrorTextEdit();
        void updateOutputTextEdit();
        void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
        void processError(QProcess::ProcessError error);
private:
        QProcess* pProcess;
        QString standardData;
        QMessageBox *box;

};

#endif // TESTPING_H

/*********************************************************************
                             TestPing.cpp
*********************************************************************/

#include "TestPing.h"

PingProcess::PingProcess(QWidget* parent) : QWidget(parent)
{
    QStringList strlist;
    standardData = "";
    box = new QMessageBox;

    pProcess = new QProcess;
    // readyReadStandardError() 표준 에러가 발생하여 데이터를 기록할 때 발생
    // readyReadStandardOutput() 표준 출력이 발생하여 데이터를 기록할 때 발생
    connect( pProcess, SIGNAL(readyReadStandardError()), this, SLOT(updateErrorTextEdit()));
    connect( pProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(updateOutputTextEdit()));
    connect( pProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)) );
    connect( pProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));

    strlist << "66.249.89.99";

    pProcess->start("ping",strlist);
}

PingProcess::~PingProcess()
{
    if( pProcess )
    {
        delete pProcess;
        pProcess = NULL;
    }
}
void PingProcess::updateErrorTextEdit()
{
    //readAllStandardError() 표준에러의 내용이 기록된 QByteArray를 출력
    QByteArray newData = pProcess->readAllStandardError();
    QString text = QString::fromLocal8Bit(newData);

    standardData.append("ERROR : ");
    standardData.append(text);
    standardData.append('\n');
}

void PingProcess::updateOutputTextEdit()
{
    //readAllStandardOutput() 표준출력의 내용이 기록된 QByteArray를 출력
    QByteArray newData = pProcess->readAllStandardOutput();
    QString text = QString::fromLocal8Bit(newData);

    standardData.append(text);
    standardData.append('\n');
}

void PingProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    //QProcess::NormalExit    => 정상적인 종료
    //QProcess::CrashExit      => 비정상적인 종료
    if(exitStatus == QProcess::CrashExit)
    {
        box->setText("Conversion program crashed");
        box->show();
    }
    else if(exitCode != 0) // 0이 아니면 실패
    {
        standardData.append('\n');
        standardData.append('\n');
        standardData.append('\n');
        standardData.append("Conversion failed");

        box->setText(standardData);
        box->show();
    }
    else // 0이면 성공
    {
        standardData.append('\n');
        standardData.append('\n');
        standardData.append('\n');
        standardData.append("File created");

        box->setText(standardData);
        box->show();
    }
}

void PingProcess::processError(QProcess::ProcessError error)
{
    /*
       QProcess::FailedToStart  
       => 호출된 프로그램이 없거나 프로그램을 호출할 수 있는 권한이 없어 프로그램을 호출 할 수 없을 때
       QProcess::Crashed         
       => 프로세스가 성공적으로 시작하여 몇시간이 지난 후 고장난 경우
       QProcess::WriteError      
       => 프로세스를 쓸 때 오류가 발생 함. 예를 들어 프로세스 실행이 되지 않거나, 입력 채널이 닫혀 있을 때
       QProcess::ReadError      
       => 프로세스를 읽을 때 오류가 발생 함. 예를 들어 프로세스 실행이 되지 않을 때
    */
    if(error == QProcess::FailedToStart)
    {
        box->setText("Conversion program not found");
        box->show();
    }
}
/*********************************************************************
                             main.cpp
*********************************************************************/

#include 
#include "TestPing.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    PingProcess process;


    return app.exec();
}





이런식으로 구현이 되어 있다.

그 결과를 보게 되면,


이렇게 ping 명령어를 사용하여 나온 결과를 보여 주게 된다.

간단하게 소스 분석을 하게 되면,

strlist << "66.249.89.99";
pProcess->start("ping",strlist);

이 부분이 명령어를 시작 시키는 부분이다. 다시 말하면, cmd 창에서 ping xxx.xxx.xxx.xxx를 치는 것과
같은 부분이다.


그리고

connect 부분을 보게 되면,

connect( pProcess, SIGNAL(readyReadStandardError()), this, SLOT(updateErrorTextEdit()));
=> 실행을 시키는데 오류가 생길 때 그 오류의 내용을 저장 할때 사용함

connect( pProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(updateOutputTextEdit()));
=> 실행을 시켜 나오는 데이터를 저장 할때 사용함

connect( pProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
              this, SLOT(processFinished(int,QProcess::ExitStatus)) );
=> 명령어가 종료 되었을 때 호출이 되는 부분으로 여기에서 성공, 실패 여부가 나오게 됨

connect( pProcess, SIGNAL(error(QProcess::ProcessError)),
               this, SLOT(processError(QProcess::ProcessError)));

=> 명령을 실행 하지 못할 경우 그 이유에 대해서 알 수 있음

이렇게 정의가 되어 있다.
물론 슬롯부분은 내가 함수명을 지정한 부분들이다.

그리고 그 이외 부분은 전부 소스에 간단하게 주석을 달아 놓아 크게 설명 할 부분은 없는 것 같다.