VP.
VP.

Reputation: 16725

Qt5 Is there a way to make QLocalServer listen to abstract unix socket?

Is it possible to make a QLocalServer object listen to unix abstract socket? I don't see such possibility mentioned in qt5 docs, there only named pipe is mentioned:

Usually you would just pass in a name like "foo", but on Unix this could also be a path such as "/tmp/foo" and on Windows this could be a pipe path such as "\.\pipe\foo"

So should I create my own socket and make QLocalServer object listen to it?

int sockfd = ... // a lot of work
QLocalServer *srv = new QLocalServer(this);
srv->listen(static_cast<qintptr>(&sockfd)); // bad code

Just that sounds odd knowing how Qt abstract is and how much possibilities it provides.

Upvotes: 2

Views: 807

Answers (2)

G.M.
G.M.

Reputation: 12899

You may have solved this already but just in case...

The fact that passing a manually set up socket descriptor to QLocalServer::listen fails seemed a bit odd so I looked a bit more closely at the Qt source. The problem is that the use of qintptr as the passed parameter type is rather misleading. Looking at the code shows that the qintptr value is treated as a socket descriptor -- not a pointer to a socket descriptor as the name might suggest.

So, try changing...

srv->listen(static_cast<qintptr>(&sockfd));

to...

srv->listen(sockfd);

and see if that fixes the issue.

(Note: I've written some test code that uses the above fix with an AF_UNIX + SOCK_STREAM socket and it all appears to work as expected.)

Upvotes: 1

C&#233;sar HM
C&#233;sar HM

Reputation: 197

I cannot comment yet, sorry. I am not sure, but maybe there is a way using QUdpSocket, where the use of sockets is straight and not by piping FS.

The thing is, you can create a Server by processing incoming datagrams with:

void Server::initSocket()
{
    udpSocket = new QUdpSocket(this);
    udpSocket->bind(QHostAddress::LocalHost, 7755);

    connect(udpSocket, SIGNAL(readyRead()),
            this, SLOT(readPendingDatagrams()));
}

void Server::readPendingDatagrams()
{
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        udpSocket->readDatagram(datagram.data(), datagram.size(),
                                &sender, &senderPort);

        processTheDatagram(datagram);
    }
}

Then you can use datagram information in processTheDatagram(QByteArray datagram) to do the action you wanna do.

I hope it helps.

Upvotes: 0

Related Questions