mozcelikors
mozcelikors

Reputation: 2744

Reading from a UNIX domain socket (QLocalSocket) on Qt

I am having trouble reading from a UNIX domain socket, server application is Python-based, and I need to implement IPC to communicate to Qt application as client. Server application is tested and working with a Python client application. Here is what I have on the Qt-client side:

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

and main.cpp to fire class:

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

Now, the Unix Domain Socket connection is working fine. So, I get "connected" message. And I am sure the server is sending some data asynchronously, but my program does not enter readyRead_callback at all for some reason. I need pointers as to how to fix this problem. Any help is greately appreciated.

Upvotes: 2

Views: 2859

Answers (2)

流浪小兵
流浪小兵

Reputation: 1

how to listen unix domain socket in server? use QLocalServer, but onNewConnection not called

mServer = new QLocalServer;
connect(mServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));

Upvotes: 0

eyllanesc
eyllanesc

Reputation: 244003

The need to live in the Qt event loop, and in your case you do not have any, so it does not work for you, so change your code to:

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

Upvotes: 2

Related Questions