Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Data / file transfer via TCP
Forum Updated to NodeBB v4.3 + New Features

Data / file transfer via TCP

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 8 Posters 19.4k Views 5 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #2

    hi
    It seems fine. If you can send the QString Data, you can send anything you like.
    If you want to send a binary file, then you should never ever convert to string or char *
    as you will only get up till first 0 (zero) it finds.
    so to send say an image: (pseudo code-ish)

    QFile file("c:/mypic.jpg");
    file.open(QIODevice::ReadOnly);
    QByteArray mydata=file.readAll();
    then then clientConnection->write(mydata).
    

    On the receiver end, also read it as QByteArray and
    save to file again.

    QByteArray data;
    // read ...
    QFile file("C:/path/myimage.jpg"); // change path
    file.open(QIODevice::WriteOnly);
    file.write(data);
    file.close();
    
    1 Reply Last reply
    1
    • J Offline
      J Offline
      Jeff_T69
      wrote on last edited by
      #3

      Hi,
      thank you for your help!!
      I tried to implement it, with your advice, but my program just create an empty file.
      There could be a problem with my server class, because I did't understand how I get the bytes in a DataStream.
      I thouht the command file.readAll() reads the whole file and QDataStream puts this into my Socket.
      But now I think it isn't that easy!??

      In my 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 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;
      
          // 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(mydata);
          // disconnect
          clientConnection->disconnectFromHost();
      }
      

      In my 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;
      	
      	/*if (nextByte == currentByte) {
           QTimer::singleShot(0, this, SLOT(requestNewConnection()));
           return; 
      	}*/
      
      	currentByte = nextByte;
      	QFile file("C:/Downloads/test.zip"); // download path
      	file.open(QIODevice::WriteOnly);
      	file.write(currentByte);
      	file.close();
       
        ui.getTimeButton->setEnabled(true);
      }
      
      
      kshegunovK 1 Reply Last reply
      0
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #4

        Hi
        you must use the debugger to find out what went wrong.
        you write the size of the zip file as a header.

        Do you get the size over correctly ?
        Meaning that blockSize is actually mydata.size();
        also after
        in >> nextByte;
        if you
        qDebug() << "bytes read: " << nextByte.size();

        what you get as output?

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mcosta
          wrote on last edited by
          #5

          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();
          

          Once your problem is solved don't forget to:

          • Mark the thread as SOLVED using the Topic Tool menu
          • Vote up the answer(s) that helped you to solve the issue

          You can embed images using (http://imgur.com/) or (http://postimage.org/)

          1 Reply Last reply
          3
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by SGaist
            #6

            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));
            

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • J Jeff_T69

              Hi,
              thank you for your help!!
              I tried to implement it, with your advice, but my program just create an empty file.
              There could be a problem with my server class, because I did't understand how I get the bytes in a DataStream.
              I thouht the command file.readAll() reads the whole file and QDataStream puts this into my Socket.
              But now I think it isn't that easy!??

              In my 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 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;
              
                  // 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(mydata);
                  // disconnect
                  clientConnection->disconnectFromHost();
              }
              

              In my 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;
              	
              	/*if (nextByte == currentByte) {
                   QTimer::singleShot(0, this, SLOT(requestNewConnection()));
                   return; 
              	}*/
              
              	currentByte = nextByte;
              	QFile file("C:/Downloads/test.zip"); // download path
              	file.open(QIODevice::WriteOnly);
              	file.write(currentByte);
              	file.close();
               
                ui.getTimeButton->setEnabled(true);
              }
              
              
              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by kshegunov
              #7

              @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.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • J Offline
                J Offline
                Jeff_T69
                wrote on last edited by
                #8

                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);
                }
                
                T 1 Reply Last reply
                1
                • K Offline
                  K Offline
                  karti gesar
                  wrote on last edited by
                  #9

                  hi all,
                  If file size is 1000 kb it is possible to send all the data

                  VRoninV 1 Reply Last reply
                  0
                  • K karti gesar

                    hi all,
                    If file size is 1000 kb it is possible to send all the data

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #10

                    @karti-gesar yes, of course

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    K 1 Reply Last reply
                    0
                    • VRoninV VRonin

                      @karti-gesar yes, of course

                      K Offline
                      K Offline
                      karti gesar
                      wrote on last edited by VRonin
                      #11

                      @VRonin

                      QFile file("D:/serial_Data.txt");
                          file.open(QIODevice::ReadOnly);
                          QByteArray mydata=file.readAll();
                           socket->write(mydata);
                      //Serial_Data file size is 1072kb but only 1 kb is writting
                      
                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #12

                        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);
                        }
                        

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        2
                        • K Offline
                          K Offline
                          karti gesar
                          wrote on last edited by
                          #13

                          k i will try

                          1 Reply Last reply
                          0
                          • K Offline
                            K Offline
                            karti gesar
                            wrote on last edited by VRonin
                            #14
                            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

                            VRoninV 1 Reply Last reply
                            0
                            • K karti gesar
                              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

                              VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by VRonin
                              #15

                              @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);
                              }
                              

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              1 Reply Last reply
                              4
                              • J Jeff_T69

                                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);
                                }
                                
                                T Offline
                                T Offline
                                Talha Celik
                                wrote on last edited by
                                #16

                                @Jeff_T69 what is block size ?

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved