Как правильно определить, что конец входа был достигнут в QTCPSocket?
-
26-09-2019 - |
Вопрос
У меня есть следующий код, который читает из QTCPSocket:
QString request;
while(pSocket->waitForReadyRead())
{
request.append(pSocket->readAll());
}
Проблема с этим кодом состоит в том, что он читает все входные данные, а затем паузы в конце в течение 30 секунд. (Какое время ожидания по умолчанию.)
Какой правильный способ избежать длительного тайм-аута и обнаружить, что конец входа был достигнут? (Ответ, который позволяет избежать сигналов, является предпочтительным, потому что это должно происходить синхронно в потоке.)
Решение
Единственный способ быть уверенным, когда вы получили точное количество байтов, которые вы ожидаете. Это обычно делается путем отправки размера данных в начале пакета данных. Прочтите это сначала, а затем продолжайте зацикливаться, пока не получите все это. Альтернативой состоит в том, чтобы использовать Sentinel, определенную серию байтов, которые отмечают конец данных, но это обычно становится грязным.
Другие советы
Если вы имеете дело с ситуацией, такой как HTTP-ответ, который не содержит длину содержимого, и вы знаете, что другой конец закроет соединение после отправки данных, есть альтернативное решение.
- Используйте Socket.SetreadBuffersize, чтобы убедиться, что для всех данных, которые могут быть доставлены достаточно читаемого буфера.
- Вызовите Socket.Waitfordisconded, чтобы дождаться удаленного конца, чтобы закрыть соединение
- Используйте Socket.bytesavailabilab в качестве длины содержимого
Это работает, потому что близко соединения не отказывается от каких-либо буферизованных данных в QTCPOCKET.