Data / file transfer via TCP
-
Hi,
what do you do in server is
socket->write(data); socket->disconnectFromHost();
IMO is not correct because you should wait that the bytes are written before closing the connection for instance
socket->write(data); // Wait until data are written to the native socket buffer socket->waitForBytesWritten(); socket->disconnectFromHost();
-
Hi,
One other thing:
You are creating your QDataStream on your file buffer, then you write the block size in place of the first bytes of your file.Taking the fortune server examples code, it should be:
QByteArray block; // Data that will be sent QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_5); out << (quint64)0; // Space for size of data out << file.readAll(); // Actual data out.device()->seek(0); out << (quint64)(block.size() - sizeof(quint64));
-
@Jeff_T69
Hello,This part:
QByteArray mydata = file.readAll(); QDataStream out(&mydata, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_5); out.device()->seek(0); // sets device //out << (quint64) mydata.size(); //out << (quint16)0; out << (quint64) mydata.size(); // filesize // mydata or file.size() ??? out << mydata;
looks very suspicious. I don't get it. You read the file, then create a data stream attached to the buffer containing the file and then write it over with the
<<
operator? What exactly is it that this part of the code is trying to achieve?
I believe simply doing this is sufficient:QTcpSocket * socket = tcpServer->nextPendingConnection(); socket->write(mydata); if (!socket->waitForBytesWritten()) ; // Some error occured socket->disconnectFromHost();
Similarly on the client side:
if (tcpSocket->bytesAvailable() <= 0) return; while (tcpSocket->state() == QAbstractSocket::ConnectedState) { tcpSocket->waitForReadyRead(); file.write(tcpSocket->read(tcpSocket->bytesAvailable())); }
Additionally, don't open the file at every read, just open it once and then write. The way you're doing it, the file contents will always be overwritten on each subsequent call.
Kind regards.
EDIT:
It seems @SGaist beat me to it and posted while I was writing. I see now what the idea of the first part of the code is. -
Thank you very much for all your replies. I see what went wrong.
Now it works very well.Server Class
void Server::sendData() { QFile file("C:/Uploads/Test.zip"); if (!file.open(QFile::ReadOnly)) { ui.label_Server_Status_Header ->setText( tr("Could not open the file for reading")); return; } QByteArray block; // Data that will be sent QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_5); out << (quint64)0; // Space for size of data out << file.readAll(); // Actual data out.device()->seek(0); out << (quint64)(block.size() - sizeof(quint64)); // get the next client-connection QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); // signal connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater())); // write the string into the socket clientConnection->write(block); // Wait until data are written to the native socket buffer clientConnection->waitForBytesWritten(); // disconnect clientConnection->disconnectFromHost(); }
Client Class
// read Servers datas void Client::readData() { QDataStream in(tcpSocket); in.setVersion(QDataStream::Qt_5_5); if (blockSize == 0) { // data to read available if ( tcpSocket->bytesAvailable() < (int)sizeof(quint16) ) return; in >> blockSize; } if (tcpSocket->bytesAvailable() < blockSize) return; QByteArray nextByte; // read in >> nextByte; currentByte = nextByte; QFile file("C:/Downloads/Test.zip"); // download path file.open(QIODevice::WriteOnly); file.write(currentByte); file.close(); ui.getTimeButton->setEnabled(true); }
-
hi all,
If file size is 1000 kb it is possible to send all the data -
@karti-gesar yes, of course
-
add
socket->waitForBytesWritten(-1);
P.S.
Since your file is a text file probably what you are reading is not what you want and/or it's not solid to change. you should use:QFile file("D:/serial_Data.txt"); if(file.open(QIODevice::ReadOnly | QIODevice::Text)){ const auto mydata=QTextStream(&file).readAll(); QDataStream socketStream(socket); socketStream << mydata; socket->waitForBytesWritten(-1); }
-
k i will try
-
QFile file("D:/serial_Data.txt"); if(file.open(QIODevice::ReadOnly| QIODevice::Text)) { const auto mydata=QTextStream(&file).readAll(); QDataStream socketStream(socket); socketStream << mydata; socket->waitForBytesWritten(-1); qDebug()<<mydata.constData(); }
this what i used....for file size smaller it's working ..for huge file size it not writing
-
@karti-gesar said in data/ file transfer via TCP:
huge
You should define huge but in this case you can use:
QFile file("D:/serial_Data.txt"); if(file.open(QIODevice::ReadOnly | QIODevice::Text)){ QDataStream socketStream(socket); QTextStream fileStream(&file); for(QString mydata=fileStream.readLine();!mydata.isEmpty();mydata=fileStream.readLine()) socketStream << mydata; socket->waitForBytesWritten(-1); }