Results 1 to 2 of 2

Thread: QIODevice read returning 0 bytes on SSL connection

  1. #1
    Join Date
    Oct 2020
    Qt products

    Default QIODevice read returning 0 bytes on SSL connection

    Hey guys , the issue I have seems similar to this one:

    Let me set the context here , we have a client-server application and now we are implementing ssl on its connections.

    The implementation seems to work but it is intermitent. During the login process of the application we do many requests for data, problem is that some of them work and some of them don't with no dicerning reason as to why it hangs on a specific part.

    The crux of the problem is this method right here:

    Qt Code:
    1. /**
    2.  * \fn tcpClient::readThis( char * data, qint64 maxSize )
    3.  * Consumes the bytes from the socket
    4.  * @param data buffer that receives the data
    5.  * @param maxSize max number of bytes to be read
    6.  * @return Returns number of bytes read
    7.  */
    8. qint64 tcpClient::readThis(char * data, qint64 maxSize) {
    9. //debug.dprint( className(), __FUNCTION__, __LINE__, DBG_REDES, " > readThis() %d",maxSize);
    10. qint64 readBuffer,readNow;
    11. char *p;
    12. p = data;
    13. readBuffer = readNow = 0;
    14. while (readBuffer < maxSize) {
    15. disable_rp = true;
    16. readNow=read(p, maxSize - readBuffer);
    17. if (encryptedBytesAvailable() && readNow == 0) {
    18. #ifdef _WIN32
    19. Sleep(1000);
    20. #else
    21. sleep(1);
    22. #endif
    23. }
    24. if (readNow < 0) {
    25. debug.dprint( className(), __FUNCTION__, __LINE__, DBG_REDES, " Grave error reading data from the network!");
    26. return readBuffer;
    27. }
    28. p += readNow;
    29. readBuffer += readNow;
    30. if (readBuffer < maxSize) {
    32. qApp->processEvents();
    33. }
    34. }
    35. disable_rp = false;
    36. return readBuffer;
    37. }
    To copy to clipboard, switch view to plain text mode 

    The code eventually gets stuck in this loop due to the fact that this line:

    Qt Code:
    1. readNow=read(p, maxSize - readBuffer);
    To copy to clipboard, switch view to plain text mode 

    Read 0 bytes for no apparent reason.

    At some point the maxsize is bigger than 4kb and this bug happens , the first iteration of the loop the readNow reads 4k data then when it starts again to read the rest of the data , readNow gets 0 bytes and we get stuck in a loop.

    This code works perfectly without ssl , but when we implemented ssl this happens.

    The link I mentioned above seems to be a similar issue that I found on the forums here.

    In it I found this:

    Quote Originally Posted by wysota View Post
    Your problem is generally the fact that the iodevice has a limited read buffer and your block is larger than it. The approach you are using is generally incorrect, you should be reading the data into your own buffer and only then check the size of your buffer against the size of data you expect.

    Either like so:
    Qt Code:
    1. QByteArray buffer;
    2. while(buffer.size() < blockSize) {
    3. socket->waitForReadyRead();
    4. buffer.append(socket->readAll());
    5. }
    6. doSomethingWith(buffer);
    To copy to clipboard, switch view to plain text mode 

    or (better) like so:
    Qt Code:
    1. QByteArray m_buffer;
    3. void X::onSocketReadyRead(){
    4. m_buffer.append(socket->readAll());
    5. while(m_buffer.size()>=blockSize) processData();
    6. }
    To copy to clipboard, switch view to plain text mode 

    Problem is that I'm a relative noob in QT and C++ in general so I would need some guidance on how to use the above code to help me.
    What I can say is that we are already using onReadyRead signals , but it's not clear how I can adapt my code to use a buffer and the readAll() method.

  2. #2
    Join Date
    Mar 2009
    Brisbane, Australia
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Unix/X11 Windows
    Wiki edits

    Default Re: QIODevice read returning 0 bytes on SSL connection

    There are two separate parts to the process:
    1. Accumulating the data received
    2. When you have enough data accumulated, do something with it.

    Qt Code:
    1. QByteArray m_buffer; // <<< this a member variable in the object
    3. void X::onSocketReadyRead(){ // <<< connect to a readyRead() signal, Called if there is some data to read but not necessarily a whole "block"
    4. m_buffer.append(socket->readAll()); // <<< This is Step 1 above
    5. while(m_buffer.size()>=blockSize) // <<< While there is a "block" or more
    6. processData(); // <<< process the data for a block and remove it from m_buffer. Ideally not a long-running process.
    7. // <<< at this point we leave the slot with all complete blocks processed, and less than a whole packet in the buffer. Ready to receive more data
    8. }
    To copy to clipboard, switch view to plain text mode 
    Notice that onSocketReadyRead() does not block program flow unless a whole block (or more) has been accumulated.

    Anywhere in a "pure" Qt program you see explicit calls to processEvents() or sleep() you are probably polling rather than letting Qt deliver things for you.

Similar Threads

  1. Replies: 3
    Last Post: 3rd May 2013, 20:27
  2. QTcpSocket can't read all bytes
    By Qiieha in forum Qt Programming
    Replies: 27
    Last Post: 23rd August 2011, 15:48
  3. Can somebody show how to read bytes?
    By "BumbleBee" in forum Newbie
    Replies: 36
    Last Post: 20th April 2011, 17:57
  4. How to read only a certain amount of bytes
    By Morea in forum Qt Programming
    Replies: 1
    Last Post: 28th January 2009, 07:38
  5. QIODevice::bytesAvailable() always returning 0
    By quickNitin in forum Newbie
    Replies: 6
    Last Post: 14th June 2006, 13:04


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.