QProcess 和 QLocalSocket - 未收到 IPC 消息
QProcess and QLocalSocket - IPC messages aren't received
遵循 Fortune Client 示例。
有一个 QLocalServer
的子类,它使用 Qprocess
启动另一个应用程序(客户端),该客户端将使用 QLocalSocket
发送一些消息。只有当客户端进程退出时,只有来自客户端的第一条消息才会出现在主(服务器)应用程序中。
服务器应用程序:
localserver.h
#ifndef LOCALSERVER_H
#define LOCALSERVER_H
#include <QLocalServer>
class LocalServer : public QLocalServer
{
Q_OBJECT
public:
explicit LocalServer(QObject* prnt = nullptr);
};
#endif // LOCALSERVER_H
localserver.cpp
#include "localserver.h"
#include <QLocalSocket>
#include <QDebug>
LocalServer::LocalServer(QObject* prnt)
: QLocalServer(prnt)
{
connect(this, &QLocalServer::newConnection, this, [&]() {
qDebug() << "Socket connected";
QLocalSocket* socket = this->nextPendingConnection();
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
connect(socket, &QLocalSocket::readyRead, [&, socket]() {
qDebug() << socket->readAll();
});
});
}
main.cpp(服务器)
#include <QCoreApplication>
#include <QProcess>
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
LocalServer::removeServer("testServer");
LocalServer server;
if (server.listen("testServer")) {
QProcess process;
process.setProgram("/home/ram/work/build/QtExamples/build-LocalSocketClient-Qt_5_12_1_Desktop-Debug/LocalSocketClient");
process.start();
if (process.waitForStarted() && process.waitForFinished()) {
a.exit(0);
}
}
return a.exec();
}
客户端应用程序:
main.cpp(客户端)
#include <QCoreApplication>
#include <QLocalSocket>
#include <QTimer>
#include <QDebug>
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QLocalSocket localSocket;
QObject::connect(&localSocket, &QLocalSocket::connected, &localSocket, []() {
qDebug() << "Socket connected";
});
localSocket.setServerName("testServer");
localSocket.connectToServer();
if (localSocket.waitForConnected()) {
qDebug() << "Connected!";
auto timer = new QTimer(qApp);
QObject::connect(timer, &QTimer::timeout, &localSocket, [&localSocket]() {
static int msgCount(0);
QString msg(QString("Message from client %1").arg(++msgCount));
qDebug() << localSocket.write(msg.toLatin1()) << msg;
if (msgCount > 5) {
qApp->exit(0);
}
});
timer->start(1000);
} else {
return 1;
}
return a.exec();
}
当我 运行 两个应用程序分开时,即在服务器应用程序的 main.cpp
中没有 Qprocess
部分,我看到以下输出。
Socket connected
"Message from client 1"
"Message from client 2"
"Message from client 3"
"Message from client 4"
"Message from client 5"
在 QProcess
中,所有五个消息同时出现。
Socket connected
"Message from client 1Message from client 2Message from client 3Message from client 4Message from client 5"
我在这里遗漏了什么吗? QProcess
需要更多信息吗?
此外,我也尝试使用 system()
函数 - 它的行为相同。
切勿使用 waitXXX 方法,因为它们会阻塞事件循环以阻止信号传输。在您的情况下,数据是一个接一个地获取的,但是因为没有人消耗信息,因为信号没有传输,所以它会累积在缓冲区中,并且仅在事件循环未被阻止时显示所有文本。因此,您的解决方案不是使用 waitXXX 而是使用信号:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
LocalServer::removeServer("testServer");
LocalServer server;
if (server.listen("testServer")) {
QProcess process;
process.setProgram("/home/ram/work/build/QtExamples/build-LocalSocketClient-Qt_5_12_1_Desktop-Debug/LocalSocketClient");
process.start();
QObject::connect(&process, QOverload<int>::of(&QProcess::finished), &QCoreApplication::quit);
return a.exec();
}
return 0;
}
遵循 Fortune Client 示例。
有一个 QLocalServer
的子类,它使用 Qprocess
启动另一个应用程序(客户端),该客户端将使用 QLocalSocket
发送一些消息。只有当客户端进程退出时,只有来自客户端的第一条消息才会出现在主(服务器)应用程序中。
服务器应用程序:
localserver.h
#ifndef LOCALSERVER_H
#define LOCALSERVER_H
#include <QLocalServer>
class LocalServer : public QLocalServer
{
Q_OBJECT
public:
explicit LocalServer(QObject* prnt = nullptr);
};
#endif // LOCALSERVER_H
localserver.cpp
#include "localserver.h"
#include <QLocalSocket>
#include <QDebug>
LocalServer::LocalServer(QObject* prnt)
: QLocalServer(prnt)
{
connect(this, &QLocalServer::newConnection, this, [&]() {
qDebug() << "Socket connected";
QLocalSocket* socket = this->nextPendingConnection();
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
connect(socket, &QLocalSocket::readyRead, [&, socket]() {
qDebug() << socket->readAll();
});
});
}
main.cpp(服务器)
#include <QCoreApplication>
#include <QProcess>
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
LocalServer::removeServer("testServer");
LocalServer server;
if (server.listen("testServer")) {
QProcess process;
process.setProgram("/home/ram/work/build/QtExamples/build-LocalSocketClient-Qt_5_12_1_Desktop-Debug/LocalSocketClient");
process.start();
if (process.waitForStarted() && process.waitForFinished()) {
a.exit(0);
}
}
return a.exec();
}
客户端应用程序:
main.cpp(客户端)
#include <QCoreApplication>
#include <QLocalSocket>
#include <QTimer>
#include <QDebug>
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QLocalSocket localSocket;
QObject::connect(&localSocket, &QLocalSocket::connected, &localSocket, []() {
qDebug() << "Socket connected";
});
localSocket.setServerName("testServer");
localSocket.connectToServer();
if (localSocket.waitForConnected()) {
qDebug() << "Connected!";
auto timer = new QTimer(qApp);
QObject::connect(timer, &QTimer::timeout, &localSocket, [&localSocket]() {
static int msgCount(0);
QString msg(QString("Message from client %1").arg(++msgCount));
qDebug() << localSocket.write(msg.toLatin1()) << msg;
if (msgCount > 5) {
qApp->exit(0);
}
});
timer->start(1000);
} else {
return 1;
}
return a.exec();
}
当我 运行 两个应用程序分开时,即在服务器应用程序的 main.cpp
中没有 Qprocess
部分,我看到以下输出。
Socket connected
"Message from client 1"
"Message from client 2"
"Message from client 3"
"Message from client 4"
"Message from client 5"
在 QProcess
中,所有五个消息同时出现。
Socket connected
"Message from client 1Message from client 2Message from client 3Message from client 4Message from client 5"
我在这里遗漏了什么吗? QProcess
需要更多信息吗?
此外,我也尝试使用 system()
函数 - 它的行为相同。
切勿使用 waitXXX 方法,因为它们会阻塞事件循环以阻止信号传输。在您的情况下,数据是一个接一个地获取的,但是因为没有人消耗信息,因为信号没有传输,所以它会累积在缓冲区中,并且仅在事件循环未被阻止时显示所有文本。因此,您的解决方案不是使用 waitXXX 而是使用信号:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
LocalServer::removeServer("testServer");
LocalServer server;
if (server.listen("testServer")) {
QProcess process;
process.setProgram("/home/ram/work/build/QtExamples/build-LocalSocketClient-Qt_5_12_1_Desktop-Debug/LocalSocketClient");
process.start();
QObject::connect(&process, QOverload<int>::of(&QProcess::finished), &QCoreApplication::quit);
return a.exec();
}
return 0;
}