PDA

View Full Version : Socket Reading Advice



tntcoda
4th July 2008, 02:15
Hi,

I'm reading from a TCP socket with the code below, i have no knowledge of how much data will be sent, i just know that it will end in a specific termination sequence, so my pseudo code is:

Read available bytes from socket
check end of buffer for termination sequence
Repeat if needed

(im using synchronous sockets, so when the below function is called, i know there should be data ready to recieve)


QByteArray buffer;
QFile file(file_path);

if (!file.open(QIODevice::WriteOnly))
return false;

do
{
buffer.clear();

if(!socket->waitForReadyRead())
{
socket->disconnect();
qDebug() << "Error: "<< socket->errorString();
file.close();
return false;
}

// read from socket
buffer = socket->readAll();

if(buffer.size() == 0) // empty byte array = bad
{
socket->disconnect();
qDebug("Error: Empty buffer.");
file.close();
return false;
}

file.write(buffer); // Append current buffer chunk to file

// breaks when termination sequence found at end of buffer
} while(!TransmissionFinished(buffer, type));

file.close(); // all done


While this works, after a bit of testing I occasionally get a timeout error which results in corrupt data because a chunk is missing, and there is no real reason why it should timeout in this case which makes me think im not approaching it correctly. So if anyone could tell me if something is clearly incorrect, or if there is a more elegant way of doing this i would really appreciate it.

Many thanks for any help,

Jack

^NyAw^
4th July 2008, 09:59
Hi,

I think that the loop that you are using is a bad idea. Thing on what happens if you call "buffer = socket->readAll()" but the socket has no data yet. A simple and best way to do this is to connect the "readyRead()" signal from the socket to a slot on you will have to check if all the data has been arrived and then close the socket connection.

tntcoda
4th July 2008, 11:09
Hi,

I think that the loop that you are using is a bad idea. Thing on what happens if you call "buffer = socket->readAll()" but the socket has no data yet. A simple and best way to do this is to connect the "readyRead()" signal from the socket to a slot on you will have to check if all the data has been arrived and then close the socket connection.

Thanks, but does my blocking call to waitForReadyRead() not guarantee that when it returns with true, there will be data waiting to be read by socket->readAll()?

I would much rather take the blocking synchronous approach that using async signals/slots in this case if at all possible.

^NyAw^
4th July 2008, 11:26
Hi,

I said "readyRead()" signal, not "waitForReadyRead(int msecs)" method. Take a look at "fortuneclient" example.



I would much rather take the blocking synchronous approach that using async signals/slots in this case if at all possible.

Really? Don't know why.