【问题标题】:Reading from a UNIX domain socket (QLocalSocket) on Qt从 Qt 上的 UNIX 域套接字 (QLocalSocket) 读取
【发布时间】:2019-02-23 07:00:19
【问题描述】:

我在从 UNIX 域套接字读取时遇到问题,服务器应用程序是基于 Python 的,我需要实现 IPC 以作为客户端与 Qt 应用程序通信。服务器应用程序经过测试并与 Python 客户端应用程序一起使用。这是我在 Qt 客户端所拥有的:

unixsocket.cpp

#include "unixsocket.h"
#include <stdio.h>

UnixSocket::UnixSocket(QObject *parent) :
    QObject(parent)
{
    this->socket = new QLocalSocket (this);
}

UnixSocket::~UnixSocket(){}

void UnixSocket::Test ()
{
    connect (this->socket, SIGNAL(connected()), this, SLOT(connected_callback()));
    connect (this->socket, SIGNAL(disconnected()), this, SLOT(disconnected_callback()));
    connect (this->socket, SIGNAL(readyRead()), this, SLOT(readyRead_callback()));
    connect (this->socket, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten_callback(qint64)));

    qDebug() << "Connecting...";

    socket->connectToServer(ADAPTER_SOCKET);

    if (!socket->waitForConnected(1000))
    {
        qDebug() << "Error: " << this->socket->errorString();
    }
    else
    {
        in.setDevice(socket);
        in.setVersion(QDataStream::Qt_5_8);
        this->blockSize = 0;

    }

}

void UnixSocket::connected_callback()
{
    qDebug() << "Connected to " << socket->fullServerName();

}

void UnixSocket::disconnected_callback()
{
    qDebug() << "Disconnected!";
}

void UnixSocket::bytesWritten_callback(qint64 bytes)
{
    qDebug() << "We wrote: " << bytes;
}

void UnixSocket::readyRead_callback()
{
    qDebug() << "Reading...";
    qDebug() << "Block Size: " << this->blockSize;

    if (this->blockSize == 0) {
        // Relies on the fact that QDataStream serializes a quint32 into
        // sizeof(quint32) bytes
        if (socket->bytesAvailable() < (int)sizeof(quint32))
            return;
        in >> this->blockSize;
    }

    if (socket->bytesAvailable() < this->blockSize || in.atEnd())
        return;

    QString recvd_data;
    in >> recvd_data;
    qDebug() << recvd_data;
}

unixsocket.h

#ifndef UNIXSOCKET_H
#define UNIXSOCKET_H

#include <QObject>
#include <QAbstractSocket>
#include <QLocalSocket>
#include <QtNetwork>
#include <QIODevice>
#include <QDebug>
#include <QTextStream>
#include <QDataStream>

#define ADAPTER_SOCKET "/opt/adapter/socket"


class UnixSocket: public QObject
{
    Q_OBJECT

public:
    explicit UnixSocket(QObject *parent = 0);
    ~UnixSocket();
    void Test ();

signals:

public slots:

    void connected_callback();
    void disconnected_callback();
    void bytesWritten_callback (qint64 bytes);
    void readyRead_callback();

private:
    QLocalSocket *socket;
    QDataStream in;
    quint32 blockSize;
};

#endif // UNIXSOCKET_H

ma​​in.cpp 触发类:

int main(int argc, char* argv[])
{
    UnixSocket mUnixSocket;
    mUnixSocket.Test();
    while (1);
    return 1;
}

现在,Unix 域套接字连接工作正常。因此,我收到“已连接”消息。而且我确信服务器正在异步发送一些数据,但我的程序由于某种原因根本没有输入readyRead_callback。我需要有关如何解决此问题的指示。非常感谢任何帮助。

【问题讨论】:

  • 它可以在没有线程的情况下工作吗?
  • 很遗憾没有,已经通过将套接字实例化移动到 main 对其进行了测试
  • 那么问题不是由线程引起的,所以我建议您通过消除线程来简化示例。
  • 将你的 main 改为 int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); UnixSocket mUnixSocket; mUnixSocket.Test(); return a.exec(); } 不要使用 while(1),因为它是阻塞的,并且信号需要 Qt 事件循环。
  • 我已经发布了一个答案,另一方面我建议添加作为更新线程的使用。

标签: c++ qt sockets unix-socket qtnetwork


【解决方案1】:

需要存在于 Qt 事件循环中,在你的情况下你没有,所以它对你不起作用,所以将你的代码更改为:

int main(int argc, char *argv[]) { 
    QCoreApplication a(argc, argv);
    UnixSocket mUnixSocket; 
    mUnixSocket.Test(); 
    return a.exec(); 
}

【讨论】:

  • 你知道为什么它不能在线程中工作吗?保持 QCoreApplication 部分完好无损。
  • @mozcelikors 我觉得很奇怪,它应该可以工作,但我还有一个问题,你为什么要在线程中运行它?信号的神奇之处在于您可以避免使用线程来执行异步任务。
  • 确实如此。我刚才在想我是否真的需要一个线程,用信号/插槽来做这一切。我想我之前的思考过程并没有涉及使用信号/插槽,这就是我专注于线程的原因。所以我可以使用它目前的情况进行更深入的挖掘。感谢您的帮助!
  • @mozcelikors 在 Qt 中,如果任务很轻,您最不需要的就是线程,Qt 提供了异步工作的工具,这就是它们的魔力。
  • @mozcelikors 在 C++ 中使用 #include &lt;cstdio&gt; 而不是 #include &lt;stdio.h&gt;
猜你喜欢
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 2023-03-05
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多