PDA

View Full Version : QFile::read failed after n bytes already read



Quenix
3rd May 2013, 01:45
Hello all,

I'm new to QT, new to this forum too, student programmer, etc. In brief, new.

I tried the following example in order to learned how to do a tcp connection and how to send some bytes too.
example : http://www.qtcentre.org/threads/48209-file-transfer-through-sockets , code in the bottom of the page.
Everything work well except data reading from a file.

I wrote (copy) that code in the server part :


// Send File
QFile inputFile(FILENAME);
QByteArray read;
inputFile.open(QIODevice::ReadOnly);
while(1)
{
read.clear();
read = inputFile.read(32768*8);
qDebug() << "Read : " << read.size();
qDebug() << "Pos : " << inputFile.pos();
if(read.size() == 0)
break;

qDebug() << "Written :" << client.write(read);
client.waitForBytesWritten();

}


So, it works well, but it stop after 3 pass (while) and just sent a certain amount of bytes even if I use whatever file as input.
It seems that is the read = inputFile.read(32768*8) that is wrong, but I'm not sure.

Following is the server output. In the third pass it just read 182276 bytes and the QTCpSocket client.write(read) return -1 this time.
The amount of data received by the client = the amount sent by the server = 706564.

File transfer started
Thread called
Thread Descriptor : 21
Thread : Connected
Read : 262144
Pos : 262144
Written : 262144
Read : 262144
Pos : 524288
Written : 262144
Read : 182276
Pos : 706564
Written : -1
QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState
Read : 0
Pos : 706564
QAbstractSocket::waitForDisconnected() is not allowed in UnconnectedState
Thread : File transfer completed
/home/serge/Bureau/tp6-server/tp6-server s'est terminé avec le code 0

Thank you very much for your time.

ChrisW67
3rd May 2013, 02:26
QFile::read failed after n bytes already read
There's nothing wrong with the read() in the code you show us. It reads two blocks of 256k and the remainder of the file is 182276 bytes assuming the file you have opened contains 706564 bytes.

The "QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState" indicates that the TCP connection to the other end has been closed, possibly deliberately by the other end, possibly some other error condition. Nothing in the code we can see would help diagnose this. Try looking at QTcpSocket::error() or connecting to the error() signal.

Quenix
3rd May 2013, 11:24
Thank you for your quick reply ChrisW67


There's nothing wrong with the read() in the code you show us. It reads two blocks of 256k and the remainder of the file is 182276 bytes assuming the file you have opened contains 706564 bytes.

The file is bigger than 706564 bytes. I tried with another file with the same size and it read the same way.


The "QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState" indicates that the TCP connection to the other end has been closed, possibly deliberately by the other end, possibly some other error condition. Nothing in the code we can see would help diagnose this. Try looking at QTcpSocket::error() or connecting to the error() signal.

I just take a quick look this morning at that with wireshark and it seems that the client side is resetting (RST) for an unknown reason when the last QTpSocket::write happens in the server side. I will take the time to investigate this afternoon with QTcpSocket::error().

Thank you for your help,

Serge

Quenix
3rd May 2013, 20:27
Just for the record :

Finally, I managed my QAbstractSocket::waitForBytesWritten() with the following code from the QT documentation and I don't get the error message


client.disconnectFromHost();
if(client.state() == QAbstractSocket::UnconnectedState ||
client.waitForDisconnected(1000))
qDebug("Disconnected!");
else
qDebug() << "Error when DisconnectFromHost :" << client.error();


The was no "read" error at all. In fact, the problem was in the client side.
I just forget to read in the QTcpSocket until there was not data. In the exemple in the link that I posted, the client read just one time.
This way, the server read and write data and the client read it.
The second time the server read data and write it in the TCPSocket, but it is not read or flushed because the client doesn't read it.
And the third time, the server read data and it is not able to write it in the socket.

This is the new client code. The previous code didn't have the while(client->waitForReadyRead()) but just a one time waitForReadyRead. That was my problem from the beginning.


QFile file(filename);
if(!(file.open(QIODevice::Append)))
{
qDebug("File connot be opened.");
exit(0);
}
else
{
while(client->waitForReadyRead())
{
QByteArray read = client->read(client->bytesAvailable());
qDebug() << "Read : " << read.size();
qDebug() << "Written : " << file.write(read);
}
}


file.close();


Thanks for all.