【发布时间】:2011-01-07 18:58:43
【问题描述】:
我正在使用 Qt 在 linux 中编码。我知道使用 popen 或 QProcess 我可以从我的程序中启动终端,但是我该如何写入呢?我谷歌周围的人都在建议 fork() 和 pipe()。 我的目的是对终端进行 ICMP ping,并在 ping 成功时停止。我用 popen 成功了,但我无法停止 ping 过程,因此我的程序无法运行。
【问题讨论】:
我正在使用 Qt 在 linux 中编码。我知道使用 popen 或 QProcess 我可以从我的程序中启动终端,但是我该如何写入呢?我谷歌周围的人都在建议 fork() 和 pipe()。 我的目的是对终端进行 ICMP ping,并在 ping 成功时停止。我用 popen 成功了,但我无法停止 ping 过程,因此我的程序无法运行。
【问题讨论】:
您不会向终端写入任何内容,因为没有终端。您将要运行的程序的名称及其参数作为QProcess::start 方法的参数传递。如果您只需要知道 ping 是否成功,则检查您之前使用 QProcess::start 启动的进程的退出代码就足够了;你不必阅读它的输出。
如果 ping 没有收到任何回复 数据包它会以代码退出 1.如果同时指定了包计数和截止期限,并且小于计数 数据包被收到的时间 截止日期到了,它也将 退出代码1。在其他错误上 以代码 2 退出。否则退出 使用代码 0。这使得可以 使用退出代码查看主机是否 活着与否。
默认情况下,Linux 下的ping 会一直运行,直到您停止它为止。但是,您可以使用 -c X 选项仅发送 X 个数据包,并使用 -w X 选项将整个过程的超时设置为 X 秒。通过这种方式,您可以限制 ping 的运行时间。
下面是一个使用QProcess 在 Windows 上运行 ping 程序的工作示例。对于 Linux,您必须相应地更改 ping 选项(例如 -n 到 -c)。在示例中,ping 最多运行 X 次,其中 X 是您为 Ping 类构造函数提供的选项。只要这些执行中的任何一个返回退出代码 0(表示成功),就会发出 result 信号,其值为 true。如果没有成功执行,则发出 result 信号,值为 false。
#include <QCoreApplication>
#include <QObject>
#include <QProcess>
#include <QTimer>
#include <QDebug>
class Ping : public QObject {
Q_OBJECT
public:
Ping(int count)
: QObject(), count_(count) {
arguments_ << "-n" << "1" << "example.com";
QObject::connect(&process_,
SIGNAL(finished(int, QProcess::ExitStatus)),
this,
SLOT(handlePingOutput(int, QProcess::ExitStatus)));
};
public slots:
void handlePingOutput(int exitCode, QProcess::ExitStatus exitStatus) {
qDebug() << exitCode;
qDebug() << exitStatus;
qDebug() << static_cast<QIODevice*>(QObject::sender())->readAll();
if (!exitCode) {
emit result(true);
} else {
if (--count_) {
QTimer::singleShot(1000, this, SLOT(ping()));
} else {
emit result(false);
}
}
}
void ping() {
process_.start("ping", arguments_);
}
signals:
void result(bool res);
private:
QProcess process_;
QStringList arguments_;
int count_;
};
class Test : public QObject {
Q_OBJECT
public:
Test() : QObject() {};
public slots:
void handle(bool result) {
if (result)
qDebug() << "Ping suceeded";
else
qDebug() << "Ping failed";
}
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Test test;
Ping ping(3);
QObject::connect(&ping,
SIGNAL(result(bool)),
&test,
SLOT(handle(bool)));
ping.ping();
app.exec();
}
#include "main.moc"
【讨论】:
QProcess::start。在示例中,它只是 ping,因为如果 ping 程序位于 PATH 环境变量中列出的目录之一中就足够了。但是,如果不是,或者您不想依靠 PATH 变量,则必须提供完整路径。顺便一提;您可能希望接受我的回答作为您问题的解决方案。