views:

30

answers:

1

I have the following code that reads from a QTCPSocket:

QString request;

while(pSocket->waitForReadyRead())
{
    request.append(pSocket->readAll());
}

The problem with this code is that it reads all of the input and then pauses at the end for 30 seconds. (Which is the default timeout.)

What is the proper way to avoid the long timeout and detect that the end of the input has been reached? (An answer that avoids signals is preferred because this is supposed to be happening synchronously in a thread.)

+2  A: 

The only way to be sure is when you have received the exact number of bytes you are expecting. This is commonly done by sending the size of the data at the beginning of the data packet. Read that first and then keep looping until you get it all. An alternative is to use a sentinel, a specific series of bytes that mark the end of the data but this usually gets messy.

Arnold Spence
@Arnold: Well, this is an HTTP request handler, so any HTTP request that sends the `Content-length` header will be easy to handle.
George Edison
You also need to add some timeouts, becouse if someone would attack your service, it could send Content-length, and send no data. I gues that 30 seconds timeout is to much. Maybe you should do like try max 3 retries of 5 second timeout, and assume that connection is broken
Kamil Klimek
+1 This is THE correct answer. This is TCP, a streaming protocol. You must interpret the stream to determine whether the input has been completely transmitted.
andref