Получите пинг от удаленной цели с помощью Qt (Windows / Linux)

В настоящее время я использую этот код для получения пинга целевой системы.
Однако пока он работает только под Linux и, вероятно, зависит от настроек локали.
Добавить поддержку для окон, вероятно, будет еще сложнее.
Есть ли простой способ или библиотека, чтобы получить пинг целевой системы? Я в основном работаю с Qt, поэтому было бы идеально, если бы я мог работать с QSockets.

#ifndef _WIN32
QProcess ping;
ping.start("ping", QStringList() << "-c 1" << m_sHostName);
if(ping.waitForFinished(250) ) {
while(ping.canReadLine()) {
QString line = ping.readLine();
if(line.contains("time=")) {
int iStart = line.indexOf("time=") + 5;
int iStop = line.indexOf(" ms");
QStringRef latency(&line, iStart, iStop-iStart);

m_vNetwork_s.append(time_s);
m_vLatency_ms.append(QString(latency.toLocal8Bit()).toDouble());
break;
}
}
}
#endif

8

Решение

Вам нужно написать свой код для этого без QAbstractSocket, Короче говоря, этот базовый класс не был разработан для этого варианта использования.

Причина в том, что вам нужно использовать необработанные сокеты и запускать от имени пользователя root; именно поэтому вы обычно видите установленный флаг setuid на исполняемом файле ping в Linux.

ICMP «без установления соединения», и поэтому класс Qt для него неосуществим, поскольку он не обеспечивает отправку данных на конкретный хост и т. Д.

Вы можете прочитать более подробное объяснение здесь.

2

Другие решения

Вы можете пропинговать как Windows, так и Linux, используя это:

   QStringList parameters;
#if defined(WIN32)
parameters << "-n" << "1";
#else
parameters << "-c 1";
#endif

parameters << m_sHostName;

int exitCode = QProcess::execute("ping", parameters);
if (exitCode==0) {
// it's alive
} else {
// it's dead
}
12

Код Неджата у меня тоже не сработал. Возможно, это специфично для Windows (протестировано на Windows 7 x64 + Qt 5.6).
Кажется, что команда Ping отличается от параметров и значений и требует их разделения при создании QProcess.

Таким образом, вместо того, чтобы передавать «-n 1» за один раз, вам нужно будет передавать «-n» и «1» отдельно.

По сути, с помощью кода Неджата это будет:

int exitCode = QProcess::execute("ping", QStringList()
<< "-n" << "1"<< m_sHostName);
if (exitCode==0) {
// it's alive
} else {
// it's dead
}

Проверено и работает сейчас.

7

Метод ping возвращает событие кода выхода 0, если цель недоступна в Windows.
Вы должны проанализировать вывод команды.
Следующий пример работает на Windows и Linux:

class MyClass {
private slots:
void OnPing();
void OnPingEnded();
private:
Process mPingProcess;
};

void MyClass::OnPing()
{
connect(&mPingProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(OnPingEnded()));
#ifdef __linux__
mPingProcess.start("ping", QStringList() << "-c" << "1" << ui->ip->text());
#else
mPingProcess.start("ping", QStringList() << "-n" << "1" << ui->ip->text());
#endif
}

void MyClass::OnPingEnded()
{
QByteArray output = mPingProcess.readAllStandardOutput();
if (!output.isEmpty())
{
qDebug() << output;
if (-1 != QString(output).indexOf("ttl", 0, Qt::CaseInsensitive))
{
qDebug() << "PING OK";
}
else
{
qDebug() << "PING KO";
}
}
}
1
По вопросам рекламы [email protected]