Pergunta

I'm puzzled with a problem designing a simple QLocalServer-QLocalSocket IPC system.

The QLocalServer waits for a new connection and connect the signals to the proper slots.

void CommandProcessor::onNewConnection()
{
    QLocalSocket* pLocal = _server->nextPendingConnection();

    connect(pLocal,SIGNAL(disconnected()),this,SLOT(onSocketDisconnected()));
    connect(pLocal,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
    connect(pLocal,SIGNAL(error(QLocalSocket::LocalSocketError)),this, SLOT(onSocketError(QLocalSocket::LocalSocketError)));

    qDebug("Socket connected. addr=%p", pLocal);
}

The readyRead slot implementation is:

void CommandProcessor::onSocketReadyRead() 
{
    QLocalSocket* pLocalSocket = (QLocalSocket *) sender();
    qDebug("SocketReadyRead. addr=%p", pLocalSocket);

    QDataStream in(pLocalSocket);
    in.setVersion(QDataStream::Qt_5_2);
    pLocalSocket->readAll(); 


    qDebug("%s pLocalSocket->bytesAvailable() = %d", Q_FUNC_INFO, pLocalSocket->bytesAvailable());
}

This readAll is done intentionally to check how i'm getting two readyRead signals in sequence (from the same slot pointer, I verified that).

The client operation is fairly straightforward:

   QByteArray data;
    QDataStream out(&data, QIODevice::ReadWrite);
    out.setVersion(QDataStream::Qt_5_2);

    cmd.toDataStream(out);

    // write blocksize at first field

    out.device()->seek(0);
    out << data.size() - sizeof(BLOCKSIZE_T);
    qint64 bw = _socket->write(data);

The _socket->write(data) call triggers duplicate readyRead at server (even when the server side has read all data with ReadAll call).

Any indication of where I should look?

Foi útil?

Solução

The semantics of QIODevice are such that readyRead signal simply means that there is likely data to be available for reading. It doesn't mean that there's surely data available, and it doesn't mean that a particular amount of data is guaranteed to be available. Implementations certainly do their best to avoid spurious signals, but they are free to issue any number of "spurious" ones. It would be a much worse problem (a bug, in fact!) if a readyRead signal was missed.

What you're supposed to do is to read whatever data is available when you get the signal. That's all. There are absolutely no guarantees that you will get the data in any particular "chunking". For example, if one end of a connection does a single, 1kByte write, the other end of the connection may get any number of readyRead signals.

All that is guaranteed is that if you only read data when you get a readyRead signal, you won't miss any data - thus you don't need to do reads from anywhere but a slot connected to a readyRead signal.

So, what you're seeing is perfectly OK. You need to handle any amount of data being available when a readyRead fires. Including zero bytes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top