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. Check QDataStream data availability

Check QDataStream data availability

Scheduled Pinned Locked Moved General and Desktop
15 Posts 4 Posters 13.8k Views 1 Watching
  • 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.
  • L Offline
    L Offline
    luca
    wrote on last edited by
    #1

    Hi all,
    I use a QDataStream to get data from a socket this way:
    @
    QTcpSocket *socket;
    socket = ...... ;
    QDataStream in(socket);
    QString str;
    in >> str;
    ....
    ....
    @

    is there a way to check if there are some data to read ?

    I need something like this:
    @
    while (data_available)
    {
    in >> str;
    }
    @

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #2

      Hi,

      did you try to read the documentation of QTcpSocket? if you follow the class hierarchy, you come to "QIODevice":http://doc.qt.nokia.com/latest/qiodevice.html which has some signals:

      • void aboutToClose ()
      • void bytesWritten ( qint64 bytes )
      • void readChannelFinished ()
      • void readyRead ()

      There are also some methods, that can be used:

      • qint64 bytesAvailable()
      • bool canReadLine () const

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • L Offline
        L Offline
        luca
        wrote on last edited by
        #3

        [quote author="Gerolf" date="1296729153"]Hi,

        did you try to read the documentation of QTcpSocket? if you follow the class hierarchy, you come to "QIODevice":http://doc.qt.nokia.com/latest/qiodevice.html which has some signals:

        • void aboutToClose ()
        • void bytesWritten ( qint64 bytes )
        • void readChannelFinished ()
        • void readyRead ()

        There are also some methods, that can be used:

        • qint64 bytesAvailable()
        • bool canReadLine () const
          [/quote]

        Yes I know.
        I can't use signal because I prefer to do all in the same function.
        canReadLine() doesn't works as expected because I have:
        @
        connect(socket, SIGNAL(readyRead()), SLOT(newData()));
        ....
        void newData()
        {
        while(socket_socket->canReadLine())
        {

        }
        ...
        }
        @
        and it never enter in the "while" .

        But bytesAvailable() do the works. I didn't know about it...

        @
        connect(socket, SIGNAL(readyRead()), SLOT(newData()));
        ....
        void newData()
        {
        while(socket->bytesAvailable())
        {
        QDataStream in(socket);
        QString str;
        in >> str;
        ....
        }
        ....
        }
        @

        Thanks, it solved!

        1 Reply Last reply
        0
        • G Offline
          G Offline
          goetz
          wrote on last edited by
          #4

          You should connect the socket with the datastream only once. The chunks from the TCP socket might not be complete for the datastream to fulfill it's work.

          Also, you connect socket to the slot, but read from socket_socket in the slot.

          http://www.catb.org/~esr/faqs/smart-questions.html

          1 Reply Last reply
          0
          • L Offline
            L Offline
            luca
            wrote on last edited by
            #5

            [quote author="Volker" date="1296732271"]

            Also, you connect socket to the slot, but read from socket_socket in the slot.[/quote]

            My transcription error.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              luca
              wrote on last edited by
              #6

              [quote author="Volker" date="1296732271"]You should connect the socket with the datastream only once. The chunks from the TCP socket might not be complete for the datastream to fulfill it's work.
              [/quote]

              It actually works but thanks for your suggestion.
              I changed with:
              @
              void newData()
              {
              QDataStream in(socket);
              while(socket->bytesAvailable())
              {

                   QString str;
                   in >> str;
                   ....
              }
              

              ....
              }
              @

              1 Reply Last reply
              0
              • G Offline
                G Offline
                goetz
                wrote on last edited by
                #7

                That's only little better, you still have the same problem between subsequent emits of the readyRead() signal. You should connect the socket to the datastream in the place where you get/create the socket and leave them connected for the livetime of the TPC connection.

                http://www.catb.org/~esr/faqs/smart-questions.html

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  luca
                  wrote on last edited by
                  #8

                  [quote author="Volker" date="1296739471"]That's only little better, you still have the same problem between subsequent emits of the readyRead() signal. You should connect the socket to the datastream in the place where you get/create the socket and leave them connected for the livetime of the TPC connection.[/quote]

                  So you suggest this:
                  @
                  QDataStream *in;
                  void myClass::newConnectionFromClient()
                  {
                  QTcpSocket *socket;
                  in = new QDataStream(socket);
                  socket = m_tcpServer->nextPendingConnection();
                  connect(socket, SIGNAL(readyRead()), SLOT(newData()));
                  ...
                  }

                  void myClass::newData()
                  {
                  while(socket->bytesAvailable())
                  {

                       QString str;
                       in >> str;
                       ....
                  }
                  

                  ....
                  }

                  @

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    goetz
                    wrote on last edited by
                    #9

                    In principle, yes. But make it in the correct order:

                    @
                    QDataStream *in = 0;
                    void myClass::newConnectionFromClient()
                    {
                        QTcpSocket *socket = m_tcpServer->nextPendingConnection();
                        in = new QDataStream(socket);
                        connect(socket, SIGNAL(readyRead()), SLOT(newData()));
                    ...
                    }
                    @

                    In your version the variable socket is not initialized and can lead to application crashes when calling QDataStream(socket).

                    Initialize your datastream variable in to 0 in the constructor and don't forget to delete it after you're done it (and setting in to 0 again) or delete it in the destructor (no problem to delete a null pointer, that's valid C++ and guaranteed to do nothing).

                    http://www.catb.org/~esr/faqs/smart-questions.html

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      luca
                      wrote on last edited by
                      #10

                      [quote author="Volker" date="1296741413"]In principle, yes. But make it in the correct order:

                      @
                      QDataStream *in = 0;
                      void myClass::newConnectionFromClient()
                      {
                          QTcpSocket *socket = m_tcpServer->nextPendingConnection();
                          in = new QDataStream(socket);
                          connect(socket, SIGNAL(readyRead()), SLOT(newData()));
                      ...
                      }
                      @

                      In your version the variable socket is not initialized and can lead to application crashes when calling QDataStream(socket).

                      Initialize your datastream variable in to 0 in the constructor and don't forget to delete it after you're done it (and setting in to 0 again) or delete it in the destructor (no problem to delete a null pointer, that's valid C++ and guaranteed to do nothing).[/quote]

                      Thanks,
                      I'm in dept with you.

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        dangelog
                        wrote on last edited by
                        #11

                        Watch out when using QDataStream with sockets. Always remember that QDataStream has no means to recover from short reads and writes (which won't happen in case of QTcpSocket, but may happen with files or so). That's why many examples use a mixed approach, by serializing data on a QByteArray and the prepending the length of the byte array itself as an unsigned X bits integer. On receiver's side, you read X bits, then read the corresponding amount of bytes into a bytearray, then decode using QDataStream.

                        Software Engineer
                        KDAB (UK) Ltd., a KDAB Group company

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          luca
                          wrote on last edited by
                          #12

                          [quote author="peppe" date="1296809201"]Always remember that QDataStream has no means to recover from short reads and writes (which won't happen in case of QTcpSocket, but may happen with files or so)[/quote]
                          Hi peppe,
                          what do you mean with this?

                          1 Reply Last reply
                          0
                          • D Offline
                            D Offline
                            dangelog
                            wrote on last edited by
                            #13

                            What do you think
                            @
                            QDataStream ds(socket);
                            QString string;
                            ds >> string;
                            @

                            does if there's not enough data avaialable to read to successfully decode the string?

                            Software Engineer
                            KDAB (UK) Ltd., a KDAB Group company

                            1 Reply Last reply
                            0
                            • L Offline
                              L Offline
                              luca
                              wrote on last edited by
                              #14

                              That's a good question.

                              Should it append if the sender send the string with:
                              @
                              QDataStream stream(socket);
                              QString string;
                              stream << string;
                              @
                              ?

                              1 Reply Last reply
                              0
                              • D Offline
                                D Offline
                                dangelog
                                wrote on last edited by
                                #15

                                No, it just silently fails. Therefore: do not do that.

                                Software Engineer
                                KDAB (UK) Ltd., a KDAB Group company

                                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