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. QTcpSocket - Aborting write and write progress
QtWS25 Last Chance

QTcpSocket - Aborting write and write progress

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 4 Posters 641 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.
  • S Offline
    S Offline
    steveq
    wrote on last edited by
    #1

    Hey Gurus,

    I am writing a Facebook style Messenger app, and I am really happy with its progress so far.

    I have come across a couple of problems I can't seem to solve. I have added the ability to send a file between chat rooms and it works very well. My code to send the file is this:

    	QFile file( fullName );
    
    	file.open( QIODevice::ReadOnly);
    
    	QByteArray l_vDataToBeSent, packedData, fileData;
    
    	QDataStream l_vStream(&l_vDataToBeSent, QIODevice::WriteOnly);
    
    	l_vStream.setByteOrder(QDataStream::LittleEndian);
    
    	unsigned int size = sizeof(messageType) + sizeof(unsigned int) + static_cast<unsigned int>(uuid.length()) + sizeof(unsigned int) + static_cast<unsigned int>(fileName.length()) + sizeof(unsigned int) + static_cast<uint>(file.size());
    
    	l_vStream << size;
    
    	l_vStream << messageType;
    
    	l_vStream.writeBytes( uuid.toStdString().c_str(), static_cast<unsigned int>(uuid.length()));
    	l_vStream.writeBytes( fileName.toStdString().c_str(), static_cast<unsigned int>(fileName.length()));
    
    	l_vStream << file.readAll();
    
    	prepareDatastream( &l_vDataToBeSent, &packedData );
    
    	if ( m_pTcpSocket ) m_pTcpSocket->write(packedData, packedData.length());
    
    	file.close();
    

    The prepareDatastream function encrypts the data before it is sent. All data between the clients and server is encrypted in both directions.

    My questions are these:

    • If a large file is sent (perhaps >10meg) and the user decides they want to abort the send mid-transfer, is it possible to tell QTcpSocket to abort the current write without disconnecting?

    • Is it possible to get some sort of feedback from QTcpSocket as to the status of the current write so I can display a progress indicator? I have connected a SLOT to the bytesWritten SIGNAL, but it is only ever called the once, and it contains the size of the file being sent, even though the transfer is still in progress. Consequently my progress indicator immediately jumps to 100%. So bytesWritten does not appear to be the answer.

    Thanks everyone in advance for your help.

    Steve Q. :-)

    O VRoninV 2 Replies Last reply
    0
    • S steveq

      Hey Gurus,

      I am writing a Facebook style Messenger app, and I am really happy with its progress so far.

      I have come across a couple of problems I can't seem to solve. I have added the ability to send a file between chat rooms and it works very well. My code to send the file is this:

      	QFile file( fullName );
      
      	file.open( QIODevice::ReadOnly);
      
      	QByteArray l_vDataToBeSent, packedData, fileData;
      
      	QDataStream l_vStream(&l_vDataToBeSent, QIODevice::WriteOnly);
      
      	l_vStream.setByteOrder(QDataStream::LittleEndian);
      
      	unsigned int size = sizeof(messageType) + sizeof(unsigned int) + static_cast<unsigned int>(uuid.length()) + sizeof(unsigned int) + static_cast<unsigned int>(fileName.length()) + sizeof(unsigned int) + static_cast<uint>(file.size());
      
      	l_vStream << size;
      
      	l_vStream << messageType;
      
      	l_vStream.writeBytes( uuid.toStdString().c_str(), static_cast<unsigned int>(uuid.length()));
      	l_vStream.writeBytes( fileName.toStdString().c_str(), static_cast<unsigned int>(fileName.length()));
      
      	l_vStream << file.readAll();
      
      	prepareDatastream( &l_vDataToBeSent, &packedData );
      
      	if ( m_pTcpSocket ) m_pTcpSocket->write(packedData, packedData.length());
      
      	file.close();
      

      The prepareDatastream function encrypts the data before it is sent. All data between the clients and server is encrypted in both directions.

      My questions are these:

      • If a large file is sent (perhaps >10meg) and the user decides they want to abort the send mid-transfer, is it possible to tell QTcpSocket to abort the current write without disconnecting?

      • Is it possible to get some sort of feedback from QTcpSocket as to the status of the current write so I can display a progress indicator? I have connected a SLOT to the bytesWritten SIGNAL, but it is only ever called the once, and it contains the size of the file being sent, even though the transfer is still in progress. Consequently my progress indicator immediately jumps to 100%. So bytesWritten does not appear to be the answer.

      Thanks everyone in advance for your help.

      Steve Q. :-)

      O Offline
      O Offline
      ollarch
      wrote on last edited by ollarch
      #2

      You can send data using chunks instead of sending all the data at once. On every write you can check if the user want to stop sending and abort it. On every loop call QApplication::processEvents() to let the ProgressBar paint the progress.
      Also you have to connect the signal "disconnected" or maybe "stateChanged" to know if the connection is lost during transferring.
      If the user abort the transfer you can send some kind of special message to client to let it know that the transfer is aborted.

      1 Reply Last reply
      1
      • S steveq

        Hey Gurus,

        I am writing a Facebook style Messenger app, and I am really happy with its progress so far.

        I have come across a couple of problems I can't seem to solve. I have added the ability to send a file between chat rooms and it works very well. My code to send the file is this:

        	QFile file( fullName );
        
        	file.open( QIODevice::ReadOnly);
        
        	QByteArray l_vDataToBeSent, packedData, fileData;
        
        	QDataStream l_vStream(&l_vDataToBeSent, QIODevice::WriteOnly);
        
        	l_vStream.setByteOrder(QDataStream::LittleEndian);
        
        	unsigned int size = sizeof(messageType) + sizeof(unsigned int) + static_cast<unsigned int>(uuid.length()) + sizeof(unsigned int) + static_cast<unsigned int>(fileName.length()) + sizeof(unsigned int) + static_cast<uint>(file.size());
        
        	l_vStream << size;
        
        	l_vStream << messageType;
        
        	l_vStream.writeBytes( uuid.toStdString().c_str(), static_cast<unsigned int>(uuid.length()));
        	l_vStream.writeBytes( fileName.toStdString().c_str(), static_cast<unsigned int>(fileName.length()));
        
        	l_vStream << file.readAll();
        
        	prepareDatastream( &l_vDataToBeSent, &packedData );
        
        	if ( m_pTcpSocket ) m_pTcpSocket->write(packedData, packedData.length());
        
        	file.close();
        

        The prepareDatastream function encrypts the data before it is sent. All data between the clients and server is encrypted in both directions.

        My questions are these:

        • If a large file is sent (perhaps >10meg) and the user decides they want to abort the send mid-transfer, is it possible to tell QTcpSocket to abort the current write without disconnecting?

        • Is it possible to get some sort of feedback from QTcpSocket as to the status of the current write so I can display a progress indicator? I have connected a SLOT to the bytesWritten SIGNAL, but it is only ever called the once, and it contains the size of the file being sent, even though the transfer is still in progress. Consequently my progress indicator immediately jumps to 100%. So bytesWritten does not appear to be the answer.

        Thanks everyone in advance for your help.

        Steve Q. :-)

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

        Sending in chuncks is the way to go. Something like:

        QFile* file = new QFile( fullName, this );
        QTimer* chunkTimer = new QTimer(file);
        QObject::connect(chunkTimer,&QTimer::timeout,m_pTcpSocket,[=]()->void{
        if(!m_keepReading){ //change this boolean to stop sending
        file->deleteLater();
        return;
        }
        QByteArray chunck(512,0);
        const auto actualRead = file.read(chunck.data(),512);
        m_pTcpSocket->write(chunck);
        if(actualRead<512)
        file->deleteLater();
        });
        chunkTimer.start(0);
        

        P.S.
        By looking at your code it would appear you followed a Qt4 tutorial on QTcpSocket. Since Qt 5.7 QDataStream introduced transactions to simplify the process. See https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application for an updated example that uses transactions.

        @steveq said in QTcpSocket - Aborting write and write progress:

        The prepareDatastream function encrypts the data before it is sent. All data between the clients and server is encrypted in both directions.

        Just use QSslSocket instead of QTcpSocket, there's no need to do it manually

        "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
        3
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Maybe also connecting to QTcpSocket::bytesWritten() to do further writing can help here.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          2
          • S Offline
            S Offline
            steveq
            wrote on last edited by
            #5

            Hi Guys,

            Thanks so much for your replies and advice.

            @VRonin thanks heaps for the code snippet too. I wish I'd known about QSslSocket a while ago!! Hehe.

            Steve Q. :-)

            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