I took threaded fortune server example for experimenting with tcp socket communication.

The idea is to make a server that will accept many clients. When a connected client sends message to server, the server would sent this message to all other connected clients.

Here is the code so far:
server.h
Qt Code:
  1. #ifndef SERVER_H
  2. #define SERVER_H
  3.  
  4. #include <QStringList>
  5. #include <QTcpServer>
  6.  
  7. class Server : public QTcpServer
  8. {
  9. Q_OBJECT
  10.  
  11. public:
  12. Server ( QObject *parent = 0 );
  13.  
  14. protected:
  15. void incomingConnection ( int socketDescriptor );
  16.  
  17. private slots:
  18. void fromClient(QByteArray data);
  19.  
  20. signals:
  21. void toClient(QByteArray data);
  22. };
  23. #endif
To copy to clipboard, switch view to plain text mode 
server.cpp:
Qt Code:
  1. #include "server.h"
  2. #include "serverthread.h"
  3.  
  4. Server::Server ( QObject *parent )
  5. : QTcpServer ( parent )
  6. {
  7. listen ( QHostAddress::Any, 8888 );
  8. }
  9.  
  10. void Server::incomingConnection ( int socketDescriptor )
  11. {
  12. ServerThread *thread = new ServerThread ( socketDescriptor, this );
  13. connect ( thread, SIGNAL ( finished() ), thread, SLOT ( deleteLater() ) );
  14. connect ( thread, SIGNAL ( started() ), thread, SLOT ( threadStarted() ) );
  15. connect ( thread, SIGNAL ( fromClient ( QByteArray ) ), this, SLOT ( fromClient ( QByteArray ) ) );
  16. connect ( this, SIGNAL ( toClient ( QByteArray ) ), thread, SLOT ( toClient ( QByteArray ) ) );
  17. thread->start();
  18. }
  19.  
  20. void Server::fromClient ( QByteArray data )
  21. {
  22. ServerThread* thread = static_cast<ServerThread*> ( sender() );
  23. disconnect ( this, SIGNAL ( toClient ( QByteArray ) ), thread, SLOT ( toClient ( QByteArray ) ) );
  24. emit toClient ( data );
  25. connect ( this, SIGNAL ( toClient ( QByteArray ) ), thread, SLOT ( toClient ( QByteArray ) ) );
  26. }
To copy to clipboard, switch view to plain text mode 
serverthread.h:
Qt Code:
  1. #ifndef SERVERTHREAD_H
  2. #define SERVERTHREAD_H
  3.  
  4. #include <QThread>
  5. #include <QTcpSocket>
  6.  
  7. class ServerThread : public QThread
  8. {
  9. Q_OBJECT
  10.  
  11. public:
  12. ServerThread ( int socketDescriptor, QObject *parent );
  13. ~ServerThread ();
  14.  
  15. void run();
  16.  
  17. signals:
  18. void error ( QTcpSocket::SocketError socketError );
  19. void fromClient(QByteArray data);
  20.  
  21. public slots:
  22. void toClient(QByteArray data);
  23.  
  24. private slots:
  25. void socketDisconnected();
  26. void receiveMessage();
  27. void threadStarted();
  28.  
  29. private:
  30. int socketDescriptor;
  31. QTcpSocket* client;
  32. quint16 blockSize;
  33.  
  34. QByteArray createQByteArray(QString str);
  35. };
  36. #endif
To copy to clipboard, switch view to plain text mode 
serverthread.cpp
Qt Code:
  1. #include "serverthread.h"
  2.  
  3. #include <QtNetwork>
  4.  
  5. ServerThread::ServerThread ( int socketDescriptor, QObject *parent )
  6. : QThread ( parent ), socketDescriptor ( socketDescriptor )
  7. {
  8. blockSize = 0;
  9. }
  10.  
  11. ServerThread::~ServerThread ( )
  12. {
  13. }
  14.  
  15. void ServerThread::run()
  16. {
  17. exec();
  18. }
  19.  
  20. void ServerThread::socketDisconnected()
  21. {
  22. quit();
  23. }
  24.  
  25. void ServerThread::threadStarted()
  26. {
  27. client = new QTcpSocket(this);
  28.  
  29. connect ( client, SIGNAL ( disconnected() ),
  30. this, SLOT ( socketDisconnected() ) );
  31.  
  32. connect ( client, SIGNAL ( readyRead() ),
  33. this, SLOT ( receiveMessage() ) );
  34.  
  35. if ( !client->setSocketDescriptor ( socketDescriptor ) )
  36. {
  37. emit error ( client->error() );
  38. return;
  39. }
  40. }
  41.  
  42. void ServerThread::receiveMessage()
  43. {
  44. QDataStream in ( client );
  45. in.setVersion ( QDataStream::Qt_4_0 );
  46.  
  47. if ( blockSize == 0 )
  48. {
  49. if ( client->bytesAvailable() < ( int ) sizeof ( quint16 ) )
  50. return;
  51.  
  52. in >> blockSize;
  53. }
  54. if ( client->bytesAvailable() < blockSize )
  55. return;
  56.  
  57. QString str;
  58. in >> tmp;
  59. str = QString::fromUtf8 ( qUncompress ( tmp ) );
  60.  
  61. blockSize = 0;
  62.  
  63. emit fromClient ( createQByteArray ( str ) ); //pošljemo vsem ostalim clientom povezanim na server
  64. }
  65.  
  66. QByteArray ServerThread::createQByteArray ( QString str )
  67. {
  68. QByteArray block;
  69. QDataStream out ( &block, QIODevice::WriteOnly );
  70. out.setVersion ( QDataStream::Qt_4_0 );
  71.  
  72. out << ( quint16 ) 0;
  73. out << qCompress ( str.toUtf8(),9 );
  74. out.device()->seek ( 0 );
  75. out << ( quint16 ) ( block.size() - sizeof ( quint16 ) );
  76.  
  77. return block;
  78. }
  79.  
  80. void ServerThread::toClient ( QByteArray data )
  81. {
  82. client->write ( data );
  83. }
To copy to clipboard, switch view to plain text mode 
Everithing works well if client sends one message. But if i try to send let say 1000 messages (in for loop), other clients don't receive all messages but random noumber of them. Also all clients don't receive same number of messages.

Any suggestions?

tnx