Results 1 to 5 of 5

Thread: Server sent message not reaching client

  1. #1
    Join Date
    Feb 2010
    Location
    Brazil
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Server sent message not reaching client

    I have two projects, one for the server and the other for the client:

    Server:

    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QCoreApplication a(argc, argv);
    4.  
    5. Server s;
    6. s.start(9999);
    7.  
    8. return a.exec();
    9. }
    10.  
    11. class Server : public QObject
    12. {
    13. Q_OBJECT
    14. public:
    15. explicit Server(QObject *parent = 0);
    16.  
    17. signals:
    18.  
    19. public slots:
    20. void start(int port);
    21. void newConnection();
    22. void sendMsg();
    23.  
    24. private:
    25. QTcpServer m_server;
    26. QList<QTcpSocket*> m_clientList;
    27. QTimer m_timer;
    28.  
    29. };
    30.  
    31. Server::Server(QObject *parent) :
    32. QObject(parent)
    33. {
    34. QObject::connect(&m_server,SIGNAL(newConnection()),this,SLOT(newConnection()));
    35. QObject::connect(&m_timer,SIGNAL(timeout()),this,SLOT(sendMsg()));
    36. m_timer.setInterval(1000);
    37. m_timer.start();
    38. }
    39.  
    40. void Server::start(int port)
    41. {
    42. m_server.listen(QHostAddress::Any,port);
    43. }
    44.  
    45. void Server::newConnection()
    46. {
    47. qDebug() << "NEW CONNECTION!";
    48. m_clientList.append(m_server.nextPendingConnection());
    49. qDebug() << m_clientList.count();
    50. }
    51.  
    52. void Server::sendMsg()
    53. {
    54. foreach(QTcpSocket* socket, m_clientList)
    55. {
    56. socket->write("test");
    57. qDebug() << "send: " << socket->peerAddress();
    58. }
    59. }
    To copy to clipboard, switch view to plain text mode 

    Client:
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QCoreApplication a(argc, argv);
    4.  
    5. Client c;
    6. c.connectToHost("localhost",9999);
    7.  
    8. return a.exec();
    9. }
    10.  
    11. class Client : public QObject
    12. {
    13. Q_OBJECT
    14. public:
    15. explicit Client(QObject *parent = 0);
    16.  
    17. signals:
    18.  
    19. public slots:
    20. void connectToHost(QString hostName, int port);
    21. void read();
    22.  
    23. private:
    24. QTcpSocket m_client;
    25.  
    26. };
    27.  
    28. Client::Client(QObject *parent) :
    29. QObject(parent)
    30. {
    31. QObject::connect(&m_client,SIGNAL(readyRead()),this,SLOT(read()));
    32. }
    33.  
    34. void Client::connectToHost(QString hostName, int port)
    35. {
    36. m_client.connectToHost(hostName,port);
    37. }
    38.  
    39. void Client::read()
    40. {
    41. QDataStream in(&m_client);
    42. in.setVersion(QDataStream::Qt_4_0);
    43. QString msg;
    44. in >> msg;
    45. qDebug() << msg;
    46. }
    To copy to clipboard, switch view to plain text mode 

    It should print 'test' on the client, but it prints an empty string. What am I missing?

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,552
    Thanks
    13
    Thanked 1,579 Times in 1,508 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Server sent message not reaching client

    Two things.

    First you are writing four raw bytes to the stream and the receiver is expecting a QDataStream containing a serialised QString. It is likely (though not guaranteed, see next point) that the four bytes arrive in one call to readyRead() and that when trying to stream a QString out of a QDataStream will result in these being treated as a string length (followed by no string data). Either both ends use QDataStream or neither does.

    Secondly you are assuming payload bytes written together in one operation are sent and arrive in a single packet and trigger only a single readyRead() signal. This is not the case in general for TCP. This is dealt with by buffering data until you have a complete payload before trying to decode it.

  3. #3
    Join Date
    Feb 2010
    Location
    Brazil
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Server sent message not reaching client

    Okay, now I'm using QDataStream on both ends. Changed Server::sendMsg() to:

    Qt Code:
    1. void Server::sendMsg()
    2. {
    3. foreach(QTcpSocket* socket, m_clientList)
    4. {
    5. QByteArray block;
    6. QDataStream out(&block,QIODevice::WriteOnly);
    7. out.setVersion(QDataStream::Qt_4_0);
    8. out << QString("test");
    9. socket->write(block);
    10. qDebug() << "send: " << socket->peerAddress();
    11. }
    12. }
    To copy to clipboard, switch view to plain text mode 

    Its working now. Thanks.

    I assume the buffering is done by sending the block size before the message itself, like in the fortune examples? So I should always send the size first? Is it always done this way?

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,552
    Thanks
    13
    Thanked 1,579 Times in 1,508 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Server sent message not reaching client

    QDataStream serialises a QString by writing a size then the bytes of the string. This size is what allows the reading QDataStream to know when this serialised string ends and the next element in the stream begins.

    If you have not changed the receiver at all then you will still come to grief if you send a particularly large string that arrives in two or more packets (try sending QString(2048, 'A')). You need to make sure you have a complete message before you attempt to stream your data out of it. For binary data streams you would typically do this with your own payload size value sent before the payload (e.g. the serialised string with its size), buffer data until you have at least that many bytes, then process the payload leaving excess bytes in the buffer.

  5. #5
    Join Date
    Feb 2010
    Location
    Brazil
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Server sent message not reaching client

    Could you help me understand the fortune client example? Here's the readFortune() code with a few of my comments and questions, can you tell me if I understood the code correctly?

    Qt Code:
    1. void Client::readFortune()
    2. {
    3. QDataStream in(tcpSocket);
    4. in.setVersion(QDataStream::Qt_4_0);
    5.  
    6. if (blockSize == 0) {
    7. /*
    8. If the size of the data received is less than what is required to store the block size, do nothing
    9. */
    10. if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
    11. return;
    12.  
    13. in >> blockSize;
    14. }
    15.  
    16. /*
    17.   Is this where the buffering takes place?
    18.   bytesAvailable() return will grow each time readyRead() is emitted, until its value is equal to blockSize
    19.   */
    20. if (tcpSocket->bytesAvailable() < blockSize)
    21. return;
    22.  
    23. QString nextFortune;
    24. /*
    25.   This is where the data is read.
    26.   If we reach this part of the code, it means we have the complete data, and its safe to read and use it.
    27.   */
    28. in >> nextFortune;
    29.  
    30.  
    31. /*
    32.   Why use QTimer and not call requestNewFortune() directly?
    33.   */
    34. if (nextFortune == currentFortune) {
    35. QTimer::singleShot(0, this, SLOT(requestNewFortune()));
    36. return;
    37. }
    38.  
    39. currentFortune = nextFortune;
    40. statusLabel->setText(currentFortune);
    41. getFortuneButton->setEnabled(true);
    42. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Problem with tcp - client receive message
    By gelman in forum Newbie
    Replies: 3
    Last Post: 25th August 2011, 14:35
  2. TCP Client / Server
    By bmarsden in forum Qt Programming
    Replies: 4
    Last Post: 8th October 2010, 10:18
  3. Client Server
    By electronicboy in forum General Programming
    Replies: 3
    Last Post: 29th October 2009, 10:10
  4. How I can get the message from client
    By mraittin in forum Qt Programming
    Replies: 2
    Last Post: 7th September 2007, 13:41
  5. client-server how?
    By nongentesimus in forum Newbie
    Replies: 6
    Last Post: 28th November 2006, 09:25

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.