Qt 5.2: QLocalServer получает дублированные сигналы readyRead

Я озадачен проблемой проектирования простой системы 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).

Любой признак того, где я должен смотреть?

1

Решение

Семантика QIODevice такие, что readyRead Сигнал просто означает, что есть вероятные данные, которые будут доступны для чтения. Это не означает, что данные, безусловно, доступны, и это не означает, что определенный объем данных гарантированно будет доступен. Реализации, конечно, делают все возможное, чтобы избежать ложных сигналов, но они могут выдавать любое количество «ложных» сигналов. Это было бы гораздо более серьезной проблемой (ошибка, на самом деле!), Если readyRead сигнал был пропущен.

Что вы должны сделать, это прочитать все доступные данные, когда вы получите сигнал. Это все. Нет абсолютно никаких гарантий, что вы будете получать данные в какой-то конкретной «порции». Например, если один конец соединения выполняет однократную запись размером 1 Кбайт, другой конец соединения может получить любое число readyRead сигналы.

Все, что гарантировано, это то, что если вы только читать данные, когда вы получаете readyRead сигнал, вы не пропустите никаких данных — таким образом, вам не нужно делать чтение из любого места, кроме слота, подключенного к readyRead сигнал.

Итак, то, что вы видите, совершенно нормально. Вы должны обрабатывать любое количество данных, доступных, когда readyRead пожары. Включая ноль байтов.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]