我正在使用 Qt 在 linux 中编码。我知道使用 popen 或 QProcess 我可以从我的程序中启动终端,但是我该如何写入呢?我谷歌周围的人都在建议 fork() 和 pipe()。我的目的是对终端进行 ICMP ping,并在 ping 成功时停止。我用 popen 做到了,但我无法停止 ping 进程,因此我的程序无法运行。
1 回答
您不会向终端写入任何内容,因为没有终端。您将要运行的程序的名称及其参数作为QProcess::start
方法的参数传递。如果您只需要知道 ping 是否成功,则检查您之前使用的进程的退出代码就足够了QProcess::start
;你不必阅读它的输出。
如果 ping 根本没有收到任何回复数据包,它将以代码 1 退出。如果同时指定了数据包计数和截止时间,并且在截止时间到达时收到的数据包少于计数,它也会以代码 1 退出。在其他错误中,它以代码 2 退出。否则,它以代码 0 退出。这使得可以使用退出代码来查看主机是否处于活动状态。
默认情况ping
下在 Linux 下运行,直到你停止它。但是,您可以使用-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"