Come determinare correttamente che la fine del ciclo di ingresso è stato raggiunto in un QTCPSocket?
-
26-09-2019 - |
Domanda
Ho il seguente codice che legge da un QTCPSocket:
QString request;
while(pSocket->waitForReadyRead())
{
request.append(pSocket->readAll());
}
Il problema con questo codice è che esso legge tutti gli input e poi si ferma alla fine per 30 secondi. (Che è il timeout predefinito.)
Qual è il modo corretto per evitare il lungo timeout e rilevare che la fine del l'ingresso è stato raggiunto? (Una risposta che i segnali Evita è preferito perché questo dovrebbe accadere in modo sincrono in un thread.)
Soluzione
L'unico modo per essere sicuri è quando si è ricevuto il numero esatto di byte che si aspettano. Questo è comunemente fatto inviando la dimensione dei dati all'inizio del pacchetto di dati. Leggi che prima e poi continuare il ciclo fino a quando si ottiene tutto. Un'alternativa è quella di utilizzare una sentinella, una specifica serie di byte che segnano la fine dei dati, ma questo di solito diventa disordinato.
Altri suggerimenti
Se hai a che fare con una situazione come una risposta HTTP che non contiene un Content-Length, e si conosce l'altra estremità chiuderà la connessione una volta che i dati sono inviati, non v'è una soluzione alternativa.
- Usa socket.setReadBufferSize per assicurarsi che ci sia sufficiente buffer di lettura per tutti i dati che possono essere inviati.
- Chiamata socket.waitForDisconnected per attendere la fine telecomando per chiudere la connessione
- Usa socket.bytesAvailable come la lunghezza del contenuto
Questo funziona perché una chiusura del collegamento non scarta i dati bufferizzati in un QTcpSocket.