ping을 구현하는 것도 방법이지만 ping 프로그램을 실행하여 결과를 사용하는 것도 좋은 방법이다.
이번에는 인터넷에서 쉽게 구할 수 있는 샘플을 사용하여 ping 명령어 실행해보려 한다.
목표는 ping을 실행하고 ping의 시간을 표시하는 것을 목표로 한다.
참조할 코드가 있으면 좋으니 아래 2개를 인터넷 검색으로 찾아 사용했다.
https://github.com/edhana/qt-ping-example
GitHub - edhana/qt-ping-example: Example of a ping command (unix) using the QProcess class from QT Framework
Example of a ping command (unix) using the QProcess class from QT Framework - GitHub - edhana/qt-ping-example: Example of a ping command (unix) using the QProcess class from QT Framework
github.com
받아 실행하면 Qt 버전에 따라 다르겠지만, sleep() 함수 부분에서 문제가 생겨 수정했다.
2022.08.01 - [일하기/Qt] - warning: '_sleep' is deprecated
warning: '_sleep' is deprecated
Qt에서 sleep() 함수를 사용하면 아래와 같이 에러가 난다. warning: '_sleep' is deprecated: This function or variable has been superceded by newer library or operating system functionality. Consider u..
busyman.tistory.com
수정 후, 실행하면 아래와 같이 문제없이 돌아간다. 한글 때문에 아래와 같이 나오는데 그냥 넘어간다.
Iniciando o ping ...
read on ...
Acabou!!!
LENDO: "\r\n"
Acabou!!!
LENDO: "Ping www.google.com [172.217.161.68] 32\xB9\xD9\xC0\xCC\xC6\xAE \xB5\xA5\xC0\xCC\xC5\xCD \xBB\xE7\xBF\xEB:\r\n"
Acabou!!!
LENDO: "\xBF\xE4\xC3\xBB \xBD\xC3\xB0\xA3\xC0\xCC \xB8\xB8\xB7\xE1\xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9.\r\n"
Acabou!!!
LENDO: "172.217.161.68\xC0\xC7 \xC0\xC0\xB4\xE4: \xB9\xD9\xC0\xCC\xC6\xAE=32 \xBD\xC3\xB0\xA3=65ms TTL=112\r\n"
Acabou!!!
LENDO: "172.217.161.68\xC0\xC7 \xC0\xC0\xB4\xE4: \xB9\xD9\xC0\xCC\xC6\xAE=32 \xBD\xC3\xB0\xA3=64ms TTL=112\r\n"
Terminou o processo.
19:22:32: Debugging of E:\busyman\Qt\build-PingTeste-Desktop_Qt_5_12_12_MinGW_32_bit-Debug\debug\PingTeste.exe has finished with exit code 1.
2) QPing
https://github.com/JayTwoLab/QPing
GitHub - JayTwoLab/QPing: Ping class for Qt 5 or 6 (without user elevation) Qt 5 또는 6 기반 계정 상승 필요없는 핑
Ping class for Qt 5 or 6 (without user elevation) :kr: Qt 5 또는 6 기반 계정 상승 필요없는 핑 - GitHub - JayTwoLab/QPing: Ping class for Qt 5 or 6 (without user elevation) Qt 5 또는 6 기반 계정 상승 필요없는 핑
github.com
QPing은 컴파일에 문제가 없지만 MinGW로 빌드하여 실행하면 문제가 있는 듯하다. 개발 환경에 따라 나타날 수 있는 문제이니 그냥 넘어가자.
bmPingTest 만들기
OS별로 ping command의 출력 결과는 다양하다.
----------------
Ubuntu
----------------
$ ping www.google.com
PING www.google.com (142.250.207.100) 56(84) bytes of data.
64 bytes from kix06s11-in-f4.1e100.net (142.250.207.100): icmp_seq=1 ttl=110 time=44.8 ms
$ ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.099 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.098 ms
$ ping www.naver.com
PING www.naver.com.nheos.com (223.130.195.95) 56(84) bytes of data.
----------------
Windows
----------------
> ping 127.0.0.1
Ping 127.0.0.1 32바이트 데이터 사용:
127.0.0.1의 응답: 바이트=32 시간<1ms TTL=128
127.0.0.1의 응답: 바이트=32 시간<1ms TTL=128
> ping www.google.com
Ping www.google.com [172.217.31.132] 32바이트 데이터 사용:
172.217.31.132의 응답: 바이트=32 시간=64ms TTL=113
172.217.31.132의 응답: 바이트=32 시간=66ms TTL=113
> ping www.naver.com
Ping www.naver.com.nheos.com [223.130.195.95] 32바이트 데이터 사용:
요청 시간이 만료되었습니다.
요청 시간이 만료되었습니다.
다양한 결과를 아래와 같은 방식으로 parsing하여 시간 부분을 추출할 예정이다. OS 및 ping 출력 형식에 따라 time 부분을 잘라서 ms 단위를 us 단위로 변환한다.
bool PingTest::isWinKrOutputString(QString s, QString &r)
{
// 127.0.0.1의 응답: 바이트=32 시간<1ms TTL=128
// 172.217.31.132의 응답: 바이트=32 시간=64ms TTL=113
QRegularExpression re(" 시간[=<](\\d)*(\\.){0,1}(\\d)*ms TTL=");
QRegularExpressionMatch match = re.match(s, 0, QRegularExpression::PartialPreferFirstMatch);
bool hasMatch = match.hasMatch();
if (true == hasMatch) {
qDebug() << "match : " << match.capturedTexts();
QString responseTime = match.captured(0);
responseTime.replace(QString(" 시간"), QString(""));
responseTime.replace(QString(" TTL="), QString(""));
responseTime.replace(QString("ms"), QString(""));
r = responseTime;
//qDebug() << "responseTime : " << r;
return true;
}
return false;
}
ping 프로그램에 따라 1ms 미만을 <1ms 로 표시하기도 하고 0.987ms로 표시하기도 한다. 조건에 맞게 parsing 하고 <1ms에 대해서는 999us로 통일하여 표시한다.
qlonglong PingTest::getResponseTime(QString s)
{
// =123
// <1
qlonglong responseTime = -1;
if (true == s.startsWith(QString("="))) {
s.replace(QString("="), QString(""));
QStringList t = s.split(QString("."));
if (2 == t.count()) {
responseTime = (t[0].toLongLong() * 1000) + t[1].toLongLong();
}
else if (1 == t.count()) {
responseTime = (t[0].toLongLong() * 1000);
}
}
else if (true == s.startsWith(QString("<"))) {
s.replace(QString("<"), QString(""));
QStringList t = s.split(QString("."));
if (2 == t.count()) {
responseTime = (t[0].toLongLong() * 1000) + t[1].toLongLong() - 1;
}
else if (1 == t.count()) {
responseTime = (t[0].toLongLong() * 1000) - 1;
}
}
return responseTime;
}
결과는 아래와 같이 signal로 전달하도록 했다. mainwindow에서는 이 signal을 연결하여 정보를 받을 수 있다.
void PingTest::readyReadStandardOutput()
{
if (m_pProcessPing->isReadable()) {
QByteArray mOutputByteArray = m_pProcessPing->readAllStandardOutput();
m_OutputString = QString::fromLocal8Bit(mOutputByteArray);
QStringList outputStrings = convToLineByLine(m_OutputString);
//qDebug() << m_OutputString;
for (auto & line : outputStrings) {
qDebug() << line;
QString responseTimeString = "";
qlonglong responseTime = -1;
bool result = checkOutputString(line, responseTimeString);
if (true == result) {
responseTime = getResponseTime(responseTimeString);
qDebug() << "responseTime : " << responseTimeString << ", " << responseTime;
}
emit sigGetResponseTime(responseTime);
}
}
}
ping 결과를 받으면 QPlainTextEdit에 시간을 출력한다. 시간은 us 단위로 표시한다.
connect(pPingTest, SIGNAL(sigGetResponseTime(qlonglong)), this, SLOT(slotGetResponseTime(qlonglong)));
void MainWindow::slotGetResponseTime(qlonglong us)
{
QDateTime currTime = QDateTime::currentDateTime();
if (us >= 0) {
ui->editPingTimeRecord->textCursor().insertText("[" + currTime.toString("yyyy-MM-ddT hh:mm:ss") +
"] " + QString::number(us) + "us\n");
}
else {
ui->editPingTimeRecord->textCursor().insertText("[" + currTime.toString("yyyy-MM-ddT hh:mm:ss") +
"] timeout\n");
}
}
실행하면 아래와 같다.
정리되지 않은 코드지만 소스코드가 필요하시면 아래에서...
https://github.com/busymankr/bmPingTest
busymankr/bmPingTest
Contribute to busymankr/bmPingTest development by creating an account on GitHub.
github.com
그럼. 끝!!
'놀기 > Qt' 카테고리의 다른 글
Qt 한글 깨짐 문제 (0) | 2023.09.23 |
---|---|
QT에서 SendMessage() 사용하기 (0) | 2023.09.09 |
USB 저장 장치 제거하기 (How to eject an external drive or USB stick) (0) | 2023.09.05 |
[Qt] Widget 크기에 맞게 폰트 조절하기 (feat. QLabel을 QPixmap으로 변환) (0) | 2023.08.27 |
[Qt] QMovie로 gif 재생이 안 될 때 ..... (0) | 2023.08.07 |
댓글