Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the ping from a remote target with Qt (Windows/Linux)

Currently I use this code for retrieving the ping of a target system. However it works so far only under linux and it is likely dependent on the locale settings. To add support for windows will be likely even more complicated. Is there an easy way or library to get the ping of a target system? I mainly work with Qt, so it would be ideal if I could work with 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
like image 627
dgrat Avatar asked Apr 08 '14 11:04

dgrat


3 Answers

You can ping on both Windows and Linux using this:

   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
   }
like image 138
Nejat Avatar answered Nov 11 '22 20:11

Nejat


Nejat's code didn't work for me neither. Maybe it's Windows specific (tested on Windows 7 x64 + Qt 5.6). Ping command seems to distinct parameters and values and needs them to be passed apart when creating QProcess.

So instead of passing "-n 1" in one go, you'll need to pass "-n" and "1" separately.

Basically, with Nejat's code it would be:

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

Tested and working now.

like image 45
Bob_74 Avatar answered Nov 11 '22 20:11

Bob_74


You would need write your code for this without QAbstractSocket. In short, this base class was not designed for this use case.

The reason is that you would need to use raw sockets and run as root; that is also why you usually see the setuid flag set on the ping executable on Linux.

ICMP is "connectionless", and as such the Qt class is not feasible for it as it does not provide sending data to a specific host, etc.

You can read the more thorough explanation in here.

like image 3
lpapp Avatar answered Nov 11 '22 22:11

lpapp