Results 1 to 4 of 4

Thread: QTcpSocket and data size - how do I know the size?

  1. #1
    Join Date
    Jul 2007
    Location
    New York
    Posts
    45
    Thanks
    5
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default QTcpSocket and data size - how do I know the size?

    I have a client/server application and I am confused about how the receiving side knows when enough data is available.

    The sender (which may be client or server) will send a single char to indicate mode, then a list of elements being requested or returned.

    for instance, if the client wants to request some variables from the server, it does something like:

    Qt Code:
    1. void class::sendData()
    2. {
    3. QByteArray block;
    4. QDataStream out(&block, QIODevice::WriteOnly);
    5. out.setVersion(QDataStream::Qt_4_0);
    6.  
    7. QChar c('v'); //indicate this is a variable request with 'v' char.
    8. QStringList varlist("var1") << "var2"; //indicate the list of vars being requested.
    9.  
    10. out << c;
    11. //out << dataSize //how do I calculate this value?
    12. out << varlist;
    13.  
    14. socket->write(block);
    15. }
    To copy to clipboard, switch view to plain text mode 

    how does the receiving side know when enough data is available? In the fortune examples, it writes the size of the string in the first bytes, which is fine for a single string.

    But how do I know the size of a QStringList? is it just the sum of the lengths of the strings, or is there a sizeof command which calculates it?

    After the request has been made, the recipient would respond with something like:

    Qt Code:
    1. void class::sendData()
    2. {
    3. QByteArray block;
    4. QDataStream out(&block, QIODevice::WriteOnly);
    5. out.setVersion(QDataStream::Qt_4_0);
    6.  
    7. QChar c('V'); //indicate this is a variable response with 'V' char.
    8. QHash<QString, QVariant> vars;
    9. vars["var1"] = QVariant(100);
    10. vars["var2"] = QVariant("some data here");
    11.  
    12. out << c;
    13. //out << dataSize //how do I calculate this value?
    14. out << vars;
    15.  
    16. socket->write(block);
    17. }
    To copy to clipboard, switch view to plain text mode 

    of course, the real implementation would fetch the values for the QHash from some other place based on the list previously received, and socket is a class member created from the connection.

    The documentation says that QHash is serializable, as well as QVariant, so it tells me that the << operator will do its job, but on the receiving side, how do I know how big the data is?

    Do I have to write it to a QByteArray, then measure the size of the bytearray, then write the size of the bytearray, then write the bytearray itself? This seems like an awful lot of copying and buffering that could be avoided if I knew the size (which will always be different) ahead of time. If I am sending a long list of variables, this could be expensive!

    I was considering creating a blocking TCP thread instead of returning when not enough bytes have arrived, but this has the same problem, because >> does not seem to block. Is there a way to make >> block, or a way to pre-calculate the size instead of putting it in a bytearray?

    thanks!
    Last edited by themolecule; 26th August 2007 at 23:10.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSocket and data size - how do I know the size?

    Quote Originally Posted by themolecule View Post
    how does the receiving side know when enough data is available? In the fortune examples, it writes the size of the string in the first bytes, which is fine for a single string.
    Yes, but it does it in a generic way:
    Qt Code:
    1. out << (quint16)0;
    2. ...
    3. out.device()->seek(0);
    4. out << (quint16)(block.size() - sizeof(quint16));
    To copy to clipboard, switch view to plain text mode 
    As you can see the value written at the beginning of the block is calculated from the block size, so it doesn't matter what you write to the data stream in line 2.

    Quote Originally Posted by themolecule View Post
    But how do I know the size of a QStringList? is it just the sum of the lengths of the strings, or is there a sizeof command which calculates it?
    It depends on the encoding scheme you use. QDataStream will use this one.

    Quote Originally Posted by themolecule View Post
    Is there a way to make >> block
    No, there isn't.

  3. The following user says thank you to jacek for this useful post:

    themolecule (27th August 2007)

  4. #3
    Join Date
    Jul 2007
    Location
    New York
    Posts
    45
    Thanks
    5
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QTcpSocket and data size - how do I know the size?

    ok... well, would it work to do something like

    Qt Code:
    1. void class::sendData()
    2. {
    3. QByteArray block;
    4. QDataStream out(&block, QIODevice::WriteOnly);
    5. out.setVersion(QDataStream::Qt_4_0);
    6.  
    7. QChar c('v'); //indicate this is a variable request with 'v' char.
    8. QStringList varlist("var1") << "var2"; //indicate the list of vars being requested.
    9. QStringList varlist2("var1") << "var2"; //indicate another list of vars.
    10.  
    11. out << varlist;
    12. out << varlist2;
    13.  
    14. socket << c << (quint16) out.size() << out;
    15. }
    To copy to clipboard, switch view to plain text mode 

    or does abstractSocketItem not use the << syntax? Is this better, or just equivalent? Is it slow to rewind the pointer in a bytearray?

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSocket and data size - how do I know the size?

    Quote Originally Posted by themolecule View Post
    or does abstractSocketItem not use the << syntax? Is this better, or just equivalent?
    No, it doesn't have operator<<. You have to use QIODevice::write().

    Quote Originally Posted by themolecule View Post
    Is it slow to rewind the pointer in a bytearray?
    It shouldn't be. It's probably just a single assignment.

Bookmarks

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.