【问题标题】:Get the ping from a remote target with Qt (Windows/Linux)使用 Qt (Windows/Linux) 从远程目标获取 ping
【发布时间】:2014-05-21 00:50:33
【问题描述】:

目前我使用此代码检索目标系统的 ping。 然而,它目前仅在 linux 下有效,并且可能取决于语言环境设置。 添加对 windows 的支持可能会更加复杂。 是否有一种简单的方法或库来获取目标系统的 ping?我主要使用 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

【问题讨论】:

标签: c++ qt ping qtnetwork qabstractsocket


【解决方案1】:

您可以使用以下命令在 Windows 和 Linux 上 ping:

   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
   }

【讨论】:

  • 这种方法的问题是,我必须为主机系统的每种语言的命令行输出定义一个解析器。此外,此方法存在开销,并且可能会锁定(出于何种原因)。我个人非常讨厌这种方法!另一方面,我不愿意自己实现这样的乒乓方法,因为理论上大多数系统上应该已经有了解决方案。
  • 上述代码仅返回退出代码,因此您无需解析输出。也可以将它放在线程上以避免锁定。
  • 但是如果你想在 ms 中绘制 ping,你无论如何都需要解析 * ms。退出状态不是以毫秒为单位的延迟..
  • 是的,上面的代码只定义了远程目标的可访问性。如果您需要 ping 的输出,那么您是对的。我认为没有更好的方法了。
  • 这段代码对我不起作用!它总是返回 1! (但主机肯定是可达的)
【解决方案2】:

如果没有QAbstractSocket,您需要为此编写代码。简而言之,这个基类不是为这个用例设计的。

原因是您需要使用原始套接字并以 root 身份运行;这也是为什么您通常会在 Linux 上的 ping 可执行文件上看到设置了 setuid 标志的原因。

ICMP 是“无连接”的,因此 Qt 类不适合它,因为它不提供向特定主机发送数据等功能。

你可以阅读更详尽的解释in here

【讨论】:

    【解决方案3】:

    Nejat 的代码对我也不起作用。也许它是特定于 Windows 的(在 Windows 7 x64 + Qt 5.6 上测试)。 Ping 命令似乎区分了参数和值,需要在创建 QProcess 时将它们分开传递。

    因此,您需要分别传递“-n”和“1”,而不是一次性传递“-n 1”。

    基本上,使用 Nejat 的代码会是:

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

    已经过测试,现在可以工作了。

    【讨论】:

    • Linux 上是“-c”,仅供参考。
    【解决方案4】:

    如果目标在 Windows 中无法访问,ping 方法将返回 0 退出代码事件。 您必须解析命令输出。 以下示例适用于 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";
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-02
      • 1970-01-01
      • 2019-05-06
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多