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. why QByteArray returned from QTcpSocket::readAll() is initialized only with NULL bytes
QtWS25 Last Chance

why QByteArray returned from QTcpSocket::readAll() is initialized only with NULL bytes

Scheduled Pinned Locked Moved Solved General and Desktop
network socketreadall
6 Posts 4 Posters 2.4k 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.
  • B Offline
    B Offline
    bduminyuk
    wrote on 22 Nov 2018, 14:42 last edited by bduminyuk
    #1

    I write a network queue with socket and have a problem.

    Look at the line marked as a problem. I get the data array in the slot connected to the signal dataReady. All time the size of the array is equal to response size (expected size) from send method. It's okay. But first two arrays (replies) works correct and other arrays (third or more) contain only NULL bytes and it is not okay. I cannot get why.

    In the debugger it looks like this:

     Name   |   Value    |   Type
    data    |            | QByteArray
    |---[0] |    0 '\0'  | char
    |---[1] |    0 '\0'  | char
    ...    
    |---[N] |    0 '\0'  | char
    

    I am sure a server replies correct because I used WireShark to see what data really comes by network (I saw TCP data segment and it looks like what I want to get. It is not filled with null bytes at least).

    Code example:

    /*
     *  header file
     */
    class AsyncSocket
    {
    public:
        void send(const QByteArray &msg, int responseSize);
        bool busy() const;
    
    signals:
        void dataReady(const QByteArray &data);
    
    private slots:
        void readyRead();
    
    private:
        QTcpSocket *socket;
    };
    
    
    /*
     * Source file
     */
    void AsyncSocket::send(const QByteArray &msg, int responseSize)
    {
        socket->setReadBufferSize(responseSize);
        socket->write(msg, msg.size());
        socket->flush();
    }
    
    /*
     * I use buffer size both busy flag and size of expected message
     * If the size is 0 the socket is free.
     */
    bool AsyncSocket::busy() const 
    {
        return socket->readBufferSize();
    }
    
    
    void AsyncSocket::readyRead()
    {
        if (socket->bytesAvailable() == socket->readBufferSize())
        {
            emit (dataReady(socket->readAll())); // <----- HERE IS PROBLEM
            socket->setReadBufferSize(0);
        }
    }
    

    I skipped some implementation not related to receiving/parameters_checking to simplify the code above.

    Any idea why QTcpSocket::readAll() can return NULL filled byte array?

    K 1 Reply Last reply 23 Nov 2018, 03:15
    0
    • C Online
      C Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 22 Nov 2018, 16:56 last edited by
      #2

      I don't understand what you're trying to achieve with the readBufferSize, esp. not the busy() function... Also we don't see where you're sending the data - maybe you send null bytes there...

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

      B 1 Reply Last reply 23 Nov 2018, 08:16
      5
      • H Online
        H Online
        hskoglund
        wrote on 22 Nov 2018, 19:14 last edited by
        #3

        Hi, just guessing but the signal you emit void dataReady(const QByteArray &data); takes only a reference to the QByteArray from socket->readAll() and if the socket is deleted before you've copied the QByteArray then that could explain why you see only null bytes.
        You could try changing the the signal to void dataReady(QByteArray data);

        1 Reply Last reply
        0
        • B bduminyuk
          22 Nov 2018, 14:42

          I write a network queue with socket and have a problem.

          Look at the line marked as a problem. I get the data array in the slot connected to the signal dataReady. All time the size of the array is equal to response size (expected size) from send method. It's okay. But first two arrays (replies) works correct and other arrays (third or more) contain only NULL bytes and it is not okay. I cannot get why.

          In the debugger it looks like this:

           Name   |   Value    |   Type
          data    |            | QByteArray
          |---[0] |    0 '\0'  | char
          |---[1] |    0 '\0'  | char
          ...    
          |---[N] |    0 '\0'  | char
          

          I am sure a server replies correct because I used WireShark to see what data really comes by network (I saw TCP data segment and it looks like what I want to get. It is not filled with null bytes at least).

          Code example:

          /*
           *  header file
           */
          class AsyncSocket
          {
          public:
              void send(const QByteArray &msg, int responseSize);
              bool busy() const;
          
          signals:
              void dataReady(const QByteArray &data);
          
          private slots:
              void readyRead();
          
          private:
              QTcpSocket *socket;
          };
          
          
          /*
           * Source file
           */
          void AsyncSocket::send(const QByteArray &msg, int responseSize)
          {
              socket->setReadBufferSize(responseSize);
              socket->write(msg, msg.size());
              socket->flush();
          }
          
          /*
           * I use buffer size both busy flag and size of expected message
           * If the size is 0 the socket is free.
           */
          bool AsyncSocket::busy() const 
          {
              return socket->readBufferSize();
          }
          
          
          void AsyncSocket::readyRead()
          {
              if (socket->bytesAvailable() == socket->readBufferSize())
              {
                  emit (dataReady(socket->readAll())); // <----- HERE IS PROBLEM
                  socket->setReadBufferSize(0);
              }
          }
          

          I skipped some implementation not related to receiving/parameters_checking to simplify the code above.

          Any idea why QTcpSocket::readAll() can return NULL filled byte array?

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 23 Nov 2018, 03:15 last edited by kshegunov
          #4

          @hskoglund said in why QByteArray returned from QTcpSocket::readAll() is initialized only with NULL bytes:

          takes only a reference to the QByteArray from socket->readAll() and if the socket is deleted before you've copied the QByteArray then that could explain why you see only null bytes.

          That can't happen, and if it does then it's a bug in the user code - (directly) deleting an object in its slot handler is not allowed.

          @bduminyuk,
          just drop the readBufferSize calls all around, they do nothing for you.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          3
          • C Christian Ehrlicher
            22 Nov 2018, 16:56

            I don't understand what you're trying to achieve with the readBufferSize, esp. not the busy() function... Also we don't see where you're sending the data - maybe you send null bytes there...

            B Offline
            B Offline
            bduminyuk
            wrote on 23 Nov 2018, 08:16 last edited by
            #5

            @Christian-Ehrlicher, I try to achieve following points with the readBufferSize:

            • set expected message size
            • control socket states like: free (buffer size is NULL), busy (buffer size is not NULL) and readyForReading (buffer is full, it emits signal itself)
            • avoid redundant class members (like bool busyFlag; int maxSize;)

            @kshegunov, I found a mistake related with sizes of messages if I limit max size with readBufferSize. If the size of comming message is not equal to the expected size the readAll (by the way the read also) method returns QByteArray initialized like QByteArray(expectedSize, '\0');

            In my case I waited 3.76 Kb of data but the server sended 3.9 Kb. I have no reasons why but I got byte array like I showed above. So, I changed the size and fixed the problem. Thank you for your answers.

            K 1 Reply Last reply 23 Nov 2018, 08:20
            0
            • B bduminyuk
              23 Nov 2018, 08:16

              @Christian-Ehrlicher, I try to achieve following points with the readBufferSize:

              • set expected message size
              • control socket states like: free (buffer size is NULL), busy (buffer size is not NULL) and readyForReading (buffer is full, it emits signal itself)
              • avoid redundant class members (like bool busyFlag; int maxSize;)

              @kshegunov, I found a mistake related with sizes of messages if I limit max size with readBufferSize. If the size of comming message is not equal to the expected size the readAll (by the way the read also) method returns QByteArray initialized like QByteArray(expectedSize, '\0');

              In my case I waited 3.76 Kb of data but the server sended 3.9 Kb. I have no reasons why but I got byte array like I showed above. So, I changed the size and fixed the problem. Thank you for your answers.

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 23 Nov 2018, 08:20 last edited by kshegunov
              #6

              You're going about it the wrong way. The readBufferSize property controls the internal (read) buffer of the QTcpSocket. You don't need to touch it at all. Just read whatever is you want to read directly from the socket. If you want to make your life easier you can also make use of QDataStream and its transactions (assuming you're talking to a Qt application on the other side).

              PS.

              control socket states like: free (buffer size is NULL), busy (buffer size is not NULL) and readyForReading (buffer is full, it emits signal itself)

              This makes no sense at all. Qt will asynchronously populate the socket object's buffer, so it's never "busy" or "free".

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              4

              1/6

              22 Nov 2018, 14:42

              • Login

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