Я озадачен проблемой проектирования простой системы IPL QLocalServer-QLocalSocket.
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());
}
Это чтениеВсе сделано намеренно чтобы проверить, как я получаю два сигнала 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 (данные) триггеры вызова дублируют readyRead на сервере (даже когда серверная сторона прочитала все данные с помощью вызова ReadAll).
Любой признак того, где я должен смотреть?
Семантика QIODevice
такие, что readyRead
Сигнал просто означает, что есть вероятные данные, которые будут доступны для чтения. Это не означает, что данные, безусловно, доступны, и это не означает, что определенный объем данных гарантированно будет доступен. Реализации, конечно, делают все возможное, чтобы избежать ложных сигналов, но они могут выдавать любое количество «ложных» сигналов. Это было бы гораздо более серьезной проблемой (ошибка, на самом деле!), Если readyRead
сигнал был пропущен.
Что вы должны сделать, это прочитать все доступные данные, когда вы получите сигнал. Это все. Нет абсолютно никаких гарантий, что вы будете получать данные в какой-то конкретной «порции». Например, если один конец соединения выполняет однократную запись размером 1 Кбайт, другой конец соединения может получить любое число readyRead
сигналы.
Все, что гарантировано, это то, что если вы только читать данные, когда вы получаете readyRead
сигнал, вы не пропустите никаких данных — таким образом, вам не нужно делать чтение из любого места, кроме слота, подключенного к readyRead
сигнал.
Итак, то, что вы видите, совершенно нормально. Вы должны обрабатывать любое количество данных, доступных, когда readyRead
пожары. Включая ноль байтов.
Других решений пока нет …