Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Question to file transfer via tcp with file name
Forum Updated to NodeBB v4.3 + New Features

Question to file transfer via tcp with file name

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
8 Posts 2 Posters 2.8k Views
  • 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.
  • N Offline
    N Offline
    Nils
    wrote on last edited by
    #1

    Hello Guys,
    once more I need the help of this forum.
    I try to send file from a smartphone application to my computer.

    At the moment I get the information details via udp broadcast and then make a connection using tcp for the file transfer.

    Thats how I send the information from my smartphone app.

    void Communication::onSend() {
      mTcpSocket->connectToHost(mIpAddress, mTcpPort);
      if (mTcpSocket->waitForConnected(3000)) {
        qInfo() << "Connection estabished.";
    
        qDebug() << "Open File:" << mFileName;
    
        QFile file(mFileName);
        if (!file.open(QIODevice::ReadOnly)) {
            qWarning() << "Some error occur. Could not open the file.";
            return;
          }
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
    
        out << (quint64)0;
        out << file.readAll();
    //    out << (quint64)0 << file.fileName();
    //    QByteArray q = file.readAll();
        block.append(q);
        out.device()->seek(0);
        out << (quint64)(block.size() - sizeof(quint64));
    
        file.close();
    
        mTcpSocket->write(block);
        mTcpSocket->waitForBytesWritten();
      } else {
        qWarning() << "No connection established.";
        return;
      }
    }
    

    And that is how I try to read the information.

    void MyServer::readFromClient() {
      QDataStream in(mTcpSocket);
      QString fileName;
    
      ++mCounter;
      
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //  // Try number 1, works but without the neccesary file name
      if (mRecievedSize == 0) {
          if (mTcpSocket->bytesAvailable() < (int)sizeof(quint16))
              return;
            in >> mRecievedSize;
        }
      if (mTcpSocket->bytesAvailable() < mRecievedSize)
        return;
    
      QByteArray nextBytes;
      in >> nextBytes;
    
      currentBytes = nextBytes;
    
      QFile file(mFileName);
    
      if (file.open(QIODevice::WriteOnly)) {
          file.write(currentBytes);
          file.close();
        } else {
          qWarning() << "Could not open the file.";
        }
      
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      // Try Number 2, doesent work
      if (mRecievedSize == 0) {
          if (mTcpSocket->bytesAvailable() < sizeof(quint64))
              return;
            in >> mRecievedSize;
        }
      if (mTcpSocket->bytesAvailable() < mRecievedSize)
        return;
    
      in >> fileName;
      if (fileName != mFileName)
        mFileName = fileName;
    
     currentBytes = mTcpSocket->readAll();
    
      QFile file(mFileName);
    
      if (file.open(QIODevice::WriteOnly)) {
          file.write(currentBytes);
          file.close();
        } else {
          qWarning() << "Could not open the file.";
        }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
      qInfo() << "Method counter:" << mCounter;
    }
    

    My question is what I have to change, so that I get the file name first to create the same file on my computer and after that I want to read the data and write it to the file.

    Thanks for the help and greetings
    Nils

    jsulmJ 1 Reply Last reply
    0
    • N Nils

      Hello Guys,
      once more I need the help of this forum.
      I try to send file from a smartphone application to my computer.

      At the moment I get the information details via udp broadcast and then make a connection using tcp for the file transfer.

      Thats how I send the information from my smartphone app.

      void Communication::onSend() {
        mTcpSocket->connectToHost(mIpAddress, mTcpPort);
        if (mTcpSocket->waitForConnected(3000)) {
          qInfo() << "Connection estabished.";
      
          qDebug() << "Open File:" << mFileName;
      
          QFile file(mFileName);
          if (!file.open(QIODevice::ReadOnly)) {
              qWarning() << "Some error occur. Could not open the file.";
              return;
            }
          QByteArray block;
          QDataStream out(&block, QIODevice::WriteOnly);
      
          out << (quint64)0;
          out << file.readAll();
      //    out << (quint64)0 << file.fileName();
      //    QByteArray q = file.readAll();
          block.append(q);
          out.device()->seek(0);
          out << (quint64)(block.size() - sizeof(quint64));
      
          file.close();
      
          mTcpSocket->write(block);
          mTcpSocket->waitForBytesWritten();
        } else {
          qWarning() << "No connection established.";
          return;
        }
      }
      

      And that is how I try to read the information.

      void MyServer::readFromClient() {
        QDataStream in(mTcpSocket);
        QString fileName;
      
        ++mCounter;
        
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      //  // Try number 1, works but without the neccesary file name
        if (mRecievedSize == 0) {
            if (mTcpSocket->bytesAvailable() < (int)sizeof(quint16))
                return;
              in >> mRecievedSize;
          }
        if (mTcpSocket->bytesAvailable() < mRecievedSize)
          return;
      
        QByteArray nextBytes;
        in >> nextBytes;
      
        currentBytes = nextBytes;
      
        QFile file(mFileName);
      
        if (file.open(QIODevice::WriteOnly)) {
            file.write(currentBytes);
            file.close();
          } else {
            qWarning() << "Could not open the file.";
          }
        
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Try Number 2, doesent work
        if (mRecievedSize == 0) {
            if (mTcpSocket->bytesAvailable() < sizeof(quint64))
                return;
              in >> mRecievedSize;
          }
        if (mTcpSocket->bytesAvailable() < mRecievedSize)
          return;
      
        in >> fileName;
        if (fileName != mFileName)
          mFileName = fileName;
      
       currentBytes = mTcpSocket->readAll();
      
        QFile file(mFileName);
      
        if (file.open(QIODevice::WriteOnly)) {
            file.write(currentBytes);
            file.close();
          } else {
            qWarning() << "Could not open the file.";
          }
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      
        qInfo() << "Method counter:" << mCounter;
      }
      

      My question is what I have to change, so that I get the file name first to create the same file on my computer and after that I want to read the data and write it to the file.

      Thanks for the help and greetings
      Nils

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Nils You need to define a protocol. First send the file name, then some special byte sequence and then the data from the file. On the receiver side you then would read the file name until this special byte sequence and afterwards the file data.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • N Offline
        N Offline
        Nils
        wrote on last edited by
        #3

        I tried two changes. First I used the two commented lines from the first code snippet to send the name of the file first. From the second code part I using the try number 2 to get the the name of the file.

        I was a little surprised that it worked on the first try. But as I send a second file the method doesn't do what it should do. I get a new connection not more.
        I checked the transfer with Wireshark and it seems that the packages are send and received bei the correct ip addresses.
        But then nothing happens with it.

        @jsulm Thanks for your answer.
        If I understand it correct, I have to use some kind of special characters between the file name and the data of the file and possible some kind of end sign at the end of the transfer.

        Please correct me if I'm wrong and feel free to give me a little hint or some kind of pseudo code.

        jsulmJ 1 Reply Last reply
        0
        • N Nils

          I tried two changes. First I used the two commented lines from the first code snippet to send the name of the file first. From the second code part I using the try number 2 to get the the name of the file.

          I was a little surprised that it worked on the first try. But as I send a second file the method doesn't do what it should do. I get a new connection not more.
          I checked the transfer with Wireshark and it seems that the packages are send and received bei the correct ip addresses.
          But then nothing happens with it.

          @jsulm Thanks for your answer.
          If I understand it correct, I have to use some kind of special characters between the file name and the data of the file and possible some kind of end sign at the end of the transfer.

          Please correct me if I'm wrong and feel free to give me a little hint or some kind of pseudo code.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Nils I have one more idea :-)
          On the server side you first write the length of the file name as 2byte int (unsigned short), then file name and then the file content. On the client side you first read 2 bytes (unsigned short, quint16) then n bytes (n is the number from those first 2 bytes), put those bytes into a string, then read the rest as file content.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • N Offline
            N Offline
            Nils
            wrote on last edited by Nils
            #5

            @jsulm
            Thank you again for the fast reply.
            In my application my Client is on my Smartphone an send the data to the server, on my laptop which then reads the data from the socket.
            But I wil try it like you mention and let you know if it was successful or not.

            1 Reply Last reply
            0
            • N Offline
              N Offline
              Nils
              wrote on last edited by
              #6

              I try it out but it didn't do what I was hopping for.
              So I changed my sender(Client side) to this

                  QByteArray block;
                  QDataStream out(&block, QIODevice::WriteOnly);
              
                  out << (quint16)mFileName.size();
                  out << mFileName;
              
                  QByteArray q = file.readAll();
                  block.append(q);
                  out.device()->seek(0);
                  out << (quint64)(block.size() - sizeof(quint64));
              
                  file.close();
              
                  mTcpSocket->write(block);
                  mTcpSocket->waitForBytesWritten();
              

              and I try to receive it(server side) like this

                if (mRecievedSize == 0) {
                    if (mTcpSocket->bytesAvailable() < sizeof(quint16))
                        return;
                      in >> mRecievedSize;
                  }
              
                if (mTcpSocket->bytesAvailable() < mRecievedSize)
                    return;
              
                fileName = mTcpSocket->read(mRecievedSize);
              
                mFileName = fileName;
              
                currentBytes = mTcpSocket->readAll();
              
                QFile file(mFileName);
              
                if (file.open(QIODevice::WriteOnly)) {
                    file.write(currentBytes);
                    file.close();
                  } else {
                    qWarning() << "Could not open the file.";
                  }
              

              I get the connection and my program do something. I also get this message "QFSFileEngine::open: No file name specified", but this is because I want to create a file without a proper file name.

              What is wrong and where is my mistake in this?

              jsulmJ 1 Reply Last reply
              0
              • N Nils

                I try it out but it didn't do what I was hopping for.
                So I changed my sender(Client side) to this

                    QByteArray block;
                    QDataStream out(&block, QIODevice::WriteOnly);
                
                    out << (quint16)mFileName.size();
                    out << mFileName;
                
                    QByteArray q = file.readAll();
                    block.append(q);
                    out.device()->seek(0);
                    out << (quint64)(block.size() - sizeof(quint64));
                
                    file.close();
                
                    mTcpSocket->write(block);
                    mTcpSocket->waitForBytesWritten();
                

                and I try to receive it(server side) like this

                  if (mRecievedSize == 0) {
                      if (mTcpSocket->bytesAvailable() < sizeof(quint16))
                          return;
                        in >> mRecievedSize;
                    }
                
                  if (mTcpSocket->bytesAvailable() < mRecievedSize)
                      return;
                
                  fileName = mTcpSocket->read(mRecievedSize);
                
                  mFileName = fileName;
                
                  currentBytes = mTcpSocket->readAll();
                
                  QFile file(mFileName);
                
                  if (file.open(QIODevice::WriteOnly)) {
                      file.write(currentBytes);
                      file.close();
                    } else {
                      qWarning() << "Could not open the file.";
                    }
                

                I get the connection and my program do something. I also get this message "QFSFileEngine::open: No file name specified", but this is because I want to create a file without a proper file name.

                What is wrong and where is my mistake in this?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Nils I don't understand this part:

                block.append(q);
                out.device()->seek(0);
                out << (quint64)(block.size() - sizeof(quint64));
                

                Why do you seek and why not just:

                block.append(q);
                out << block;
                

                ?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  Nils
                  wrote on last edited by
                  #8

                  @jsulm
                  I looked at my code and it seems that I got two example mixed up.

                  Here is the link. https://stackoverflow.com/questions/30288385/how-to-send-a-file-in-qt

                  So I changed a little bit in my code.

                  Her is the sender part.

                  void Communication::onSend() {
                    mTcpSocket->connectToHost(mIpAddress, mTcpPort);
                    if (mTcpSocket->waitForConnected(3000)) {
                        qInfo() << "Connection estabished.";
                  
                        qDebug() << "Open File:" << mFileName;
                  
                        QFile file(mDataPath + "/" + mFileName);
                        if (!file.open(QIODevice::ReadOnly)) {
                            qWarning() << "Some error occur. Could not open the file.";
                            return;
                          }
                  
                        QFileInfo fileInfo(file);
                  
                        qInfo() << "Filename:" << mFileName << "; size:" << fileInfo.size();
                  
                        QDataStream out(mTcpSocket);
                  
                        out << mFileName;
                        out << QString::number(fileInfo.size());
                  
                        while (!file.atEnd()) {
                            QByteArray rawFile = file.read(5000);
                            out << rawFile;
                            mSize += rawFile.size();
                  
                            qDebug() << "Send:" << mSize << "of:" << file.size();
                            qInfo() << rawFile;
                          }
                      } else {
                        qWarning() << "No connection established.";
                        return;
                    }
                  
                    mTcpSocket->disconnectFromHost();
                    qDebug() << "Disconnected from the socket.";
                  }
                  

                  And this is my receiver part.

                  void MyServer::readFromClient() {
                    QDataStream in(mTcpSocket);
                    QString fileName;
                    QString fileSize;
                    QByteArray data;
                  
                    QFile file;
                  
                    ++mCounter;
                    qInfo() << "readFromClient counter:" << mCounter;
                  
                    if (mCounter > 1000) {
                        qWarning() << "Counter to high. Close connection.";
                        mTcpSocket->close();
                        return;
                      }
                  
                    if (mInfoRecieved) {
                        mInfoRecieved = false; 
                        in >> fileName;
                        qDebug() << "Recieved file name:" << fileName;
                        in >> fileSize;
                        qDebug() << "recieved file size:" << fileSize;
                  
                        if (!fileName.isEmpty()) {
                            mFileName = fileName;
                          }
                      }
                  
                    file.setFileName(mFileName);
                  
                  
                    if (file.open(QIODevice::Append)) {
                        while (mTcpSocket->bytesAvailable()) {
                            qDebug() << "Bytes available:" << mTcpSocket->bytesAvailable();
                            in >> data;
                            qDebug() << data;
                            file.write(data);
                          }
                  
                        file.close();
                      }
                  }
                  

                  I let me output some information for the sender and the receiver.
                  The sender give me this.

                  I SensorLogger: ../SensorLogger/src/communication.cpp:70 (void Communication::onSend()): Connection estabished.
                  D SensorLogger: ../SensorLogger/src/communication.cpp:72 (void Communication::onSend()): Open File: "170906093258.xml"
                  I SensorLogger: ../SensorLogger/src/communication.cpp:82 (void Communication::onSend()): Filename: "170906093258.xml" ; size: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 5000 of: 127977
                  // Here is the output of the data so I can check if I have an error while reading the information from the file
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 10000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 15000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 20000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 25000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 30000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 35000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 40000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 45000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 50000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 55000 of: 127977
                  D SensorLogger: ../SensorLogger/src/communication.cpp:96 (void Communication::onSend()): Send: 65000 of: 127977
                  

                  This is what I get from the receiver part.

                  we have a new connection!
                  readFromClient counter: 1
                  Recieved file name: "170906093258.xml"
                  recieved file size: "127977"
                  Bytes available: 1396
                  ""
                  readFromClient counter: 2
                  Bytes available: 1448
                  ""
                  readFromClient counter: 3
                  Bytes available: 1448
                  ""
                  readFromClient counter: 4
                  Bytes available: 1448
                  ""
                  readFromClient counter: 5
                  Bytes available: 1448
                  ""
                  readFromClient counter: 6
                  Bytes available: 1448
                  ""
                  readFromClient counter: 7
                  Bytes available: 1448
                  ""
                  readFromClient counter: 8
                  Bytes available: 1448
                  ""
                  .
                  .
                  .
                  readFromClient counter: 64
                  Bytes available: 1448
                  ""
                  readFromClient counter: 65
                  Bytes available: 1448
                  ""
                  readFromClient counter: 66
                  Bytes available: 1448
                  ""
                  readFromClient counter: 67
                  Bytes available: 709
                  ""
                  

                  I don't understand why the amount of byte read are so different from the amount I write to the socket.

                  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