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;
}