QProcess和QLocalSocket-未收到IPC消息

时间:2019-04-01 11:00:24

标签: c++ qt qt5 qprocess

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

当我分别运行两个应用程序时,即在服务器应用程序中Qprocess中没有main.cpp部分的情况下,我看到以下输出。

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()函数-行为相同。

1 个答案:

答案 0 :(得分:1)

请不要使用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;
}