我对设计一个简单的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调用读取所有数据)。
有没有迹象表明我应该去哪里看?
QIODevice
的语义是这样的,readyRead
信号只是意味着可能有数据可供读取。这并不意味着一定有可用的数据,也不意味着一定会有特定数量的数据可用。实现当然会尽最大努力避免虚假信号,但它们可以自由发布任何数量的"虚假"信号。如果错过了readyRead
信号,这将是一个更糟糕的问题(事实上是一个错误!)。
当你得到信号时,你应该做的是读取任何可用的数据。仅此而已。绝对不能保证你会在任何特定的"分块"中获得数据。例如,如果连接的一端进行单个1kByte写入,则连接的另一端可以获得任意数量的readyRead
信号。
所能保证的是,如果在获得readyRead
信号时仅读取数据,则不会错过任何数据,因此,除了连接到readyRead
信号的插槽之外,您不需要从任何位置进行读取。
所以,你所看到的是完全可以的。当readyRead
触发时,你需要处理任何可用的数据量。包括零字节。