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. Only a part of File gets send with QtcpSocket
Qt 6.11 is out! See what's new in the release blog

Only a part of File gets send with QtcpSocket

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 421 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.
  • J Offline
    J Offline
    JohnSRV
    wrote on last edited by JohnSRV
    #1

    Hello Everyone,

    I'm having a very curious case trying to send Data with QTcpSocket from a Client to a Server.
    I try to send the file Name and the Path where it should be saved on the Server Side. My Code works only for Data under 10 Ko. As soon as the File size is bigger than 10Ko only a part gets sent (14 or 12 Ko).

    Here's a part of the sender/Client Code:

                           QFileInfo fileInfo(File);								
    			out << Name;										
    			out << QString::number(fileInfo.size());			
    			QString FilePath = fileInfo.absolutePath();
    			printf(FilePath.toStdString().c_str());
    			out << FilePath;
    			int size = 0;
    			while (!File.atEnd())
    			{
    				QByteArray rawFile;
    				rawFile = File.read(1000);
    				QFileInfo rawFileInfo(rawFile);
    				size += rawFileInfo.size();
    				out << rawFile;
    			}
    

    On the Server Side

    QDataStream in(m_socket);
    	
    	QByteArray z;
    	QString fileName;
    	QString fileSize;
    	QString FilePath;
    	in >> fileName;					
    	qDebug() << fileName;
    	in >> fileSize;					
    	qDebug() << fileSize;
    	in >> FilePath;				
    	
    
    	QDir Projectpath;
    	Projectpath.mkpath(FilePath);
    
    	QFile Target(FilePath + "/" + fileName);
    	
    		if (Target.open(QIODevice::Append))
    		{
    			while (m_socket->bytesAvailable())
    			{
    
    				in >> z;
    				Target.write(z);
    			}
    			
    			Target.close();
    		}
    	
    

    The Server creates the directory and saves the File to the right path. I can't understand why it sends only a part of the File and why it works only for files under 10 ko?

    PS: qDebug()<< fileSize prints the right size of the File on the Server side. I just can't seem to write all of it to the File.

    I'm really desperate and any hint is highly appreciated. Thank you all !

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      Basically it's your responsibility to check how much data you processed

      from https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application

      The onReadyRead slot is really the most interesting one. The first thing to remember is that when we receive the readyRead we can't make any assumption on how much data is available, the signal only tells us some data is there hence there are 4 cases we need to handle:

      1. The socket did not receive enough data to be a complete message, we only received a partial
      2. There is exactly enough data in the socket buffer to read a message
      3. There is more than enough data in the socket buffer to read a message but not enough to read 2 messages
        4. There is enough data in the socket buffer to read multiple messages

      Cases 1 and 2 are entirely handled by socketStream.commitTransaction(). If there was not enough data to complete the reading when we called socketStream >> jsonData; this method will return false and we'll just exit the function and wait for more data to come in otherwise it will proceed and parse the data as a complete JSON message. Cases 3 and 4 are handled by the infinite loop. After we read the first message we try to read another one in the same way as before and break the loop only when the data in the buffer is no longer enough to be a complete JSON message.

      To facilitate the handling of differences in the expected size of the data received and the actual size, since Qt 5.7, QIODevice and QDataStream introduced transactions. Transactions work very similarly to SQL transactions: start the transaction, try and do something with the data, if everything went as expected you commit the transaction, otherwise you can go back as if you did nothing at all. QDataStream::commitTransaction will actually rollback if it detects there was an error and return false. We use this to check if socketStream >> jsonData; retrieved a full JSON document or not.". Internally socketStream >> jsonData; will read a 32bit unsigned integer that will be jsonData.size() after the read. Then it will read raw bytes of data to fill that length. If it detects any error it will set socketStream.status() to something different form QDataStream::Ok. socketStream.commitTransaction() then checks that status. If it is QDataStream::Ok it will shorten the buffer in the socket by the amount of data we successfully read and return true, otherwise it will return false maintaining the socket buffer identical to what it was before.

      "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

      • Login

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