1

我对设计一个简单的 QLocalServer-QLocalSocket IPC 系统的问题感到困惑。

QLocalServer 等待新连接并将信号连接到正确的插槽。

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

这个 readAll 是有意完成的,以检查我如何按顺序获得两个 readyRead 信号(来自同一个插槽指针,我验证了这一点)。

客户端操作相当简单:

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

_socket->write(data)调用会在服务器上触发重复的 readyRead(即使服务器端已通过 ReadAll 调用读取了所有数据)。

任何迹象表明我应该在哪里看?

4

1 回答 1

2

的语义QIODevice使得readyRead信号仅仅意味着可能有数据可供读取。这并不意味着肯定有可用的数据,也不意味着一定数量的数据可以保证可用。实现当然会尽力避免虚假信号,但它们可以自由地发出任意数量的“虚假”信号。如果readyRead信号丢失,那将是一个更糟糕的问题(实际上是一个错误!)。

您应该做的是在收到信号时读取任何可用的数据。就这样。绝对不能保证您将获得任何特定“分块”中的数据。例如,如果连接的一端执行单个 1kByte 写入,则连接的另一端可能会收到任意数量的readyRead信号。

所有可以保证的是,如果您在收到readyRead信号时读取数据,您将不会错过任何数据 - 因此您不需要从任何地方读取数据,而是从连接到readyRead信号的插槽中读取数据。

所以,你所看到的完全没问题。您需要处理readyRead发生火灾时可用的任何数量的数据。包括零字节。

于 2014-02-11T22:06:15.603 回答