Понадобилось добавить в программу небольшую пинговалку для проверки доступности ряда серверов.
Загоняю список серверов в QStringList с именем sList, после чего прогоняю подобным циклом:
for(int i=0;i<sList.size();i++){
ping = new QProcess ();
ping->start("ping", QStringList() << sList[i],QIODevice::ReadOnly);
ping->waitForFinished(300);
QString p_stdout = ping->readAllStandardOutput();
ping->close();
int TTL=p_stdout.indexOf("TTL",0);
if(TTL>=0){
qDebug()<<"Сервер "<<sList[i]<< " доступен.";
}
else{
qDebug()<<"Сервер "<<sList[i]<< " НЕ доступен!";
}
}
Но проблема тут в том, что на время waitForFinished(300); интерфейс подвисает. А когда кол-во серверов много, а проверка запускается часто - получаем зависшую прогу.
Вычитал, что можно использовать сигнал readyReadStandardOutput.
Попробовал сделать так:
for(int i=0;i<sList.size();i++){
ping = new QProcess ();
QObject::connect(ping, SIGNAL(readyReadStandardOutput ()), this, SLOT(print_ping()) );
ping->start("ping", QStringList() << sList[i],QIODevice::ReadOnly);
}
void ProgramName::print_ping()
{
QString output = ping->readAllStandardOutput ();
qDebug()<<output;
}
но print_ping вызывается неоднократно в рамках пинга одного сервера и как итог - мы имеем обновляющуюся строку QString output, которую так легко парсить на наличие в ней фразы TTL - не получится. Объединять поступающие строки в одну общую - тоже проблематично, так как пингуем несколько серверов подряд. И вторая проблема тут - мы никак не передаем имя сервера и обрабатывать результат пинга - к какому серверу оно относится - проблемно.
Какие есть способы решения, чтобы не подвисал UI и вместе с тем - иметь удобную обработку результатов?
Пока вижу только извращенный способ с записью всех результатов пинга всех серверов в одну строку, а потом уже, имя массив хостнеймов серверов, парсить куски этой строки для i-го сервере sList[ i ] в промежутках строки между sList[ i ] и sList[i+1] на наличие фразы TTL.
Но, возможно, есть варианты реализовать это как-то более грамотно?