Results 1 to 9 of 9

Thread: QTcpSocket::readyRead() lost messages, performance issue?

  1. #1
    Join Date
    May 2010
    Posts
    11
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default QTcpSocket::readyRead() lost messages, performance issue?

    Hi all,
    I have a trouble with QTcpSocket readyRead() signal.
    My Qt application act as client and the server send messages in an asyncronous way.
    The problem is that I notice that sometimes a message isn't signaled by the readyRead().
    The message is always the same message in the sequence, but the problem don't always occours.
    I'm sure that message comes because I see the network traffic with wireshark.

    Here is my client code:
    Qt Code:
    1. {
    2. // in class ctor...
    3. m_socket = new QTcpSocket(this);
    4. connect(m_socket, SIGNAL(connected()), this,SLOT(connected()));
    5. connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this,SLOT(error(QAbstractSocket::SocketError)));
    6. connect(m_socket, SIGNAL(disconnected()), this,SLOT(disconnected()));
    7. connect(m_socket, SIGNAL(readyRead()), this,SLOT(receiveMessage()));
    8. }
    9.  
    10. void XmlSocket::receiveMessage()
    11. {
    12. int bytesRead;
    13. // READ_BUF_SIZE is defined as 512 and the message I receive are 100 chars...
    14. char buf[READ_BUF_SIZE];
    15.  
    16. // read data from socket
    17. // NB: loop only if we read more than 512 bytes...
    18. QString msgString;
    19. do {
    20. bzero(buf,READ_BUF_SIZE);
    21.  
    22. bytesRead = m_socket->read(buf, READ_BUF_SIZE);
    23. if(bytesRead < 0)
    24. qCritical("Error reading data from socket %d",bytesRead);
    25. else if(bytesRead == 0)
    26. qWarning("No more data on socket...");
    27.  
    28. msgString += QString(buf);
    29. qDebug("++ %s", qPrintable(msgString));
    30. } while(bytesRead == READ_BUF_SIZE);
    31.  
    32. // emit signal with available data
    33. if(!msg.setContent(msgString))
    34. qWarning("Error setting content for string %s", qPrintable(msgString));
    35.  
    36. emit messageReceived(msg);
    37. }
    To copy to clipboard, switch view to plain text mode 

    I have see that the message that I don't receive is sent just 3 ms after the previous one...
    Send time
    [28/04 16:33:30:423] message 1, received
    [28/04 16:33:30:525] message 2, received
    [28/04 16:33:30:528] message 3, NOT RECEIVED
    [28/04 16:33:31:290] message 4, received

    This could be a performance issue???

    Now I try to solve using standard socket, but I wish to use QTcpSocket because they offer a simple API and for portability reason.

    I am using Qt 4.7.1 on linux platform.

  2. #2
    Join Date
    Apr 2009
    Location
    Italy
    Posts
    70
    Thanks
    23
    Thanked 15 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    There are many things wrong with your code, the problem is not related to network traffic.

    Please take a look at the Fortune Client example for a better way to read fixed-size blocks of data from a socket:

    http://doc.qt.nokia.com/latest/netwo...uneclient.html

    The equivalent of your receiveMessage() is Client::readFortune() in client.cpp

  3. #3
    Join Date
    May 2010
    Posts
    11
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    Hi mattc and thank you for your reply.

    I think that your suggested solution don't solve my problem, because when a message is lost the receiveMessage() isn't called at all... To prove this I have inserted a qDebug line at the firt line in the method and I see that when I lost a message the receiveMessage isn't invoked... (Note that my server isn't written in Qt and I don't know how to set the setVersion for the QDataStream).

    All my test are executed in a LAN and the messages length are under 100 characters, so I exclude that is a network issue.

    I have re implemented the class using standard socket and after an initial test the new implementation work well. I used standard socket in combination with QThread, but I wish to use a simpler implementation with only QTcpSocket.

    No one have noticed the same problem?

  4. #4
    Join Date
    Apr 2009
    Location
    Italy
    Posts
    70
    Thanks
    23
    Thanked 15 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    Here are two major problems I can see with the code you posted:

    1) if readyRead() is called and there are less than 100 bytes in the socket, you
    emit an incomplete message. The Fortune Client calls bytesAvailable()
    to prevent this.

    2) if readyRead() is called with more than 100 bytes, you are "packing" them
    together in a single message (and, as above, the last part of the message might be incomplete).
    This is weird because you say you are working with messages of 100 bytes each.

    Also, when you call QString(buf) you are making two assumption that
    I cannot verify:

    1) the received data has no embedded zeroes
    2) the received data is text encoded with the default encoding (QTextCodec::codecForCStrings())

  5. The following user says thank you to mattc for this useful post:

    Juba (7th June 2011)

  6. #5
    Join Date
    May 2010
    Posts
    11
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    Ok mattc, thank you for reviewing my code, but your post don't focus the problem...

    When readyRead() is emitted I always read the correct messages, the problem is that readRead() seems to be not emitted in certain conditions.
    The condition isn't easily reproducible, sometime a the burst of 4 messages is received, sometime the client lose the third message...

  7. #6
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    Have you tried the different connection options, such as DirectConnection (assuming slot is in same thread as signal), QueuedConnection, etc?

  8. #7
    Join Date
    May 2010
    Posts
    11
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    So far I've used the default value, but since signal and slot are in the same thread I will try the Qt::QueuedConnection value!


    Added after 43 minutes:


    I have just tryed using Qt::QueuedConnection, but the performance is worse, now when the problem occours I lost 2 messages...

    I remark that using standard socket and QThread for now I haven't see any message lost.
    Last edited by Juba; 29th April 2011 at 13:56.

  9. #8
    Join Date
    May 2010
    Posts
    11
    Thanks
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    Well, I have notice that the issue is that sometimes the underlying network layer put two xml messages in one read... And the messages are separated by a '\0' char... So thank you mattc for your useful answer.

    So even QTcpSocket and the standard socket solution works well... I prefer to use the QTcpSocket class.

    Thank you all for your answer.

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

    Default Re: QTcpSocket::readyRead() lost messages, performance issue?

    TCP doesn't have the concept of "messages". The fact that you put two blocks of data 20 bytes each on the sending side, doesn't mean the receiving end will get two blocks 20 bytes each. It might be 1 block of 40 bytes or even 40 blocks of one byte. Thus your do-while loop is flawed.
    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. QtcpSocket readyRead Problem with Java Client
    By Bernie in forum Qt Programming
    Replies: 6
    Last Post: 12th February 2011, 11:59
  2. QTcpSocket readyRead strange behavior
    By naroin in forum Qt Programming
    Replies: 46
    Last Post: 21st January 2011, 22:28
  3. QTcpSocket and readyRead and QTimer
    By cafu in forum Qt Programming
    Replies: 2
    Last Post: 18th December 2009, 13:36
  4. Question in readyRead(QTCPSOCKET)
    By morgana in forum Qt Programming
    Replies: 2
    Last Post: 24th July 2008, 18:11
  5. QTcpSocket readyRead and buffer size
    By pdoria in forum Qt Programming
    Replies: 4
    Last Post: 2nd February 2008, 10:11

Tags for this Thread

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.