Page 1 of 2 12 LastLast
Results 1 to 20 of 28

Thread: QTcpSocket can't read all bytes

  1. #1
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default QTcpSocket can't read all bytes

    Hi

    a server sends 162076 bytes to the client. The client reads the QTcpSocket and gets only 16384 bytes back and the program crashes.

    What's the best way to read all data?
    Qt Code:
    1. QByteArray byteblock = tcpsocket->read();
    2. QDataStream stream(&byteblock, QIODevice::ReadOnly);
    3. QString str;
    4. stream >> str;
    5. qDebug() << "received:" << str;
    To copy to clipboard, switch view to plain text mode 
    Debug output is: received ""

    thank u!

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    No, this is definitely wrong. Why are you using QDataStream?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    thank u for your reply!
    I saw this solution in some examples...

    what should I use instead?
    can u suggest something

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    Instead don't use QDataStream if you don't know what it does
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    what should I use?

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    You can use QTcpSocket, that you are already using. But basically everything depends on what the server is sending.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    the server writes a QByteArray to the socket:
    Qt Code:
    1. tcpsocket->write(bytearray);
    To copy to clipboard, switch view to plain text mode 

    and the bytearray has a size of 162076

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    Then read a byte array. But remember TCP is a stream protocol, don't expect to receive all data in one piece (that's the main reason why your datastream code was incorrect).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    I try it like this:
    Qt Code:
    1. void Interface::readyReadSlot()
    2. {
    3. qDebug() << "readyReadSlot()";
    4. QByteArray byteblock;
    5. while (!tcpsocket->atEnd()) {
    6. QByteArray data = tcpsocket->read(100);
    7. byteblock += data;
    8. }
    9. QDataStream stream(&byteblock, QIODevice::ReadOnly);
    10. QString string;
    11. stream >> string;
    12. qDebug() << "received:" << in_string;
    13. }
    To copy to clipboard, switch view to plain text mode 
    if the server sends a too long bytearray the Debug-Output is received " ", otherwise it's correct.
    What's wrong?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    I think you really need to learn how TCP works. There is no concept of a socket being "at end". Your approach is simply incorrect. When data arrives, append it to a buffer and when you have all the data you expect then make use of it. Of course you need to know how much data to expect. Such information needs to be encoded in the data stream (for instance you can use the newline character as a request delimiter or you can prepend the size of the record you are sending to the stream).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    the datastream consists of XML, so I could use the </end> tag as information, couldn't I?

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    No, you couldn't. You need to trace the whole document tree and see when the document is complete. QXmlStreamReader might help you with it.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #13
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    If I know the tagname of the last tag it should work:
    Qt Code:
    1. void Interface::readyReadSlot()
    2. {
    3. qDebug() << "readyReadSlot()";
    4. buffer.open(QIODevice::WriteOnly);
    5. QByteArray parcel = tcpsocket->readAll();
    6. QDataStream stream(&parcel, QIODevice::ReadOnly);
    7. QString string;
    8. stream>> string;
    9. buffer.write(parcel);
    10. buffer.close();
    11. qDebug() << "parcelsize:" << QString::number(parcel.size());
    12. qDebug() << string;
    13. if(!string.contains(QRegExp("</EndTag>\n"))){
    14. qDebug() << "wait";
    15. tcpsocket->waitForReadyRead();
    16. }
    17. else
    18. emit dataWritten(block);
    19. }
    To copy to clipboard, switch view to plain text mode 
    if the server sends exactly one parcel this works fine, but if the server sends more than one parcels, the strings are empty and the buffer writes no data to the bytearray. So maybe the way of sending the data from server is incorrect:
    Qt Code:
    1. QDataStream out(&bytearray, QIODevice::WriteOnly);
    2. QString string= message;
    3. out<< string;
    4. tcpsocket->write(bytearray);
    5.  
    6. while(!tcpsocket->waitForBytesWritten());
    To copy to clipboard, switch view to plain text mode 

    Why it didn't work? thank u for your help

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    Quote Originally Posted by Qiieha View Post
    If I know the tagname of the last tag it should work
    No. At least not in general case.

    Qt Code:
    1. void Interface::readyReadSlot()
    2. {
    3. qDebug() << "readyReadSlot()";
    4. buffer.open(QIODevice::WriteOnly);
    5. QByteArray parcel = tcpsocket->readAll();
    6. QDataStream stream(&parcel, QIODevice::ReadOnly);
    7. QString string;
    8. stream>> string;
    9. buffer.write(parcel);
    10. buffer.close();
    11. qDebug() << "parcelsize:" << QString::number(parcel.size());
    12. qDebug() << string;
    13. if(!string.contains(QRegExp("</EndTag>\n"))){
    14. qDebug() << "wait";
    15. tcpsocket->waitForReadyRead();
    16. }
    17. else
    18. emit dataWritten(block);
    19. }
    To copy to clipboard, switch view to plain text mode 
    No, it won't work, because you are using QDataStream again. And the logic is flawed, including the call to waitForReadyRead().

    I already gave you the exact recipe:
    1. append all pending data to a buffer
    2. inspect the buffer starting from the beginning until you see the "end of record" mark (or detect the end of record based on any other means available)
    3. if there is not end of record mark, just return from the function and continue when you're called next time
    4. if there is the end of record mark, remove the record from the buffer and process it leaving the rest of pending data intact.

    Note: the whole point of having a buffer is for it to persist across calls to your readyRead handler.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  15. #15
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    ok, i'll try this
    Qt Code:
    1. void Interface::readyReadSlot()
    2. {
    3. qDebug() << "readyReadSlot()";
    4. buffer.open(QIODevice::WriteOnly);
    5. QByteArray parcel = tcpsocket->readAll();
    6. buffer.write(parcel);
    7. buffer.close();
    8. qDebug() << "parcelsize:" << QString::number(parcel.size());
    9. if(!detectEndTag())
    10. return();
    11. else{
    12. processData();
    13. //remove data from buffer;
    14. //QEventLoop::quit();
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 
    and the way of sending should work?

  16. #16
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    No, it's still wrong, you are discarding previous content of the buffer.
    This is correct (by the way, there are numerous threads in this forum where I explain this particular situation, how come you didn't encounter any of the threads while using our search?):
    Qt Code:
    1. QByteArray buffer; // global or member variable
    2. void Cls::onSocketReadyRead() {
    3. buffer.append(socket->readAll());
    4. tryProcessData();
    5. }
    6.  
    7. void Cls::tryProcessData() {
    8. forever {
    9. // for the sake of the example I'm assuming my record is always 24 bytes long
    10. if(buffer.size()<24) return;
    11. QByteArray record = buffer.left(24);
    12. processRecord(record);
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 

    The above code has one small flaw introduced for purpose so that you need to understand completely what the code does before actually using it.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  17. #17
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    ok thank u!!
    the return-statement after the processRecord(record) method is missing, isn't it?

  18. #18
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    No, that's not a problem. The forever loop wouldn't make sense then. Think why the loop is there.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  19. #19
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket can't read all bytes

    the loop makes sure that no different method is executed until the record is not complete. A QEventLoop would be a different solution.

  20. #20
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTcpSocket can't read all bytes

    Quote Originally Posted by Qiieha View Post
    the loop makes sure that no different method is executed until the record is not complete.
    No, that's not the reason. And no other method would be executed anyway since there is only one thread here. There is one line of code missing from my snippet. Analyze what the whole method does line by line and you'll quickly discover what's missing. But you need to understand why the forever loop is there in the first place, it's the heart of this code.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Can somebody show how to read bytes?
    By "BumbleBee" in forum Newbie
    Replies: 36
    Last Post: 20th April 2011, 17:57
  2. Replies: 2
    Last Post: 9th June 2010, 16:08
  3. How to read only a certain amount of bytes
    By Morea in forum Qt Programming
    Replies: 1
    Last Post: 28th January 2009, 07:38
  4. socket read/write bytes
    By nowire75 in forum Newbie
    Replies: 3
    Last Post: 4th July 2007, 23:12
  5. How to read more bytes using QTcpSocket?
    By vishesh in forum Qt Programming
    Replies: 1
    Last Post: 3rd July 2007, 20:23

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.