Results 1 to 10 of 10

Thread: Reading from sockets in a multithreaded program

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Aug 2006
    Posts
    83

    Default Re: Reading from sockets in a multithreaded program

    I have a problem with using Qt networking. I want to establish a connection between a server and clients. The client is using a chalkboard and is using server to send coordinates of the lines to draw to them. For the drawing part I am using Irrlecht (because the program is not going to be the chalboard (this is just for testing), but a real 3d environment.

    I have problem getting the communication to work. I would really appreciate if someone could look at the code (I attached) and please give me some clue.

    On the server side I have:
    Qt Code:
    1. Server::Server(QObject *parent) : QTcpServer(parent)
    2. {
    3. /* maximum number of players */
    4. setMaxPendingConnections(8);
    5. m_connectedClients=-1; // none connected clients
    6. connect(this,SIGNAL(newConnection()),SLOT(newConnections()));
    7.  
    8. }
    9. void Server::send(int socket,int x1, int y1, int x2, int y2)
    10. {
    11. // I use qhash to keep information about all clients and socketDescriptors
    12. QHashIterator<int, Server_thread*> i(m_clients);
    13. while (i.hasNext()) {
    14. i.next();
    15. if(i.key() != socket) // don't send this to the client which send the info
    16. i.value()->send(x1,y1,x2,y2);
    17. }
    18. }
    19.  
    20. /* accept incoming connections */
    21. void Server::newConnections()
    22. {
    23. while(hasPendingConnections()) {
    24. QTcpSocket *socket = nextPendingConnection();
    25. Server_thread *thread = new Server_thread(socket, this);
    26. // add the client and socketDescriptor
    27. m_clients[socket->socketDescriptor()] = thread;
    28. /* delete the thread that has finished */
    29. connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    30. thread->start();
    31. }
    32. }
    To copy to clipboard, switch view to plain text mode 
    The thread for clients...
    Qt Code:
    1. Server_thread::Server_thread(QTcpSocket *socket, Server *parent)
    2. : QThread(parent)
    3. {
    4. m_parent = parent;
    5. m_socket = socket;
    6. connect(this,SIGNAL(address(QString)),this,SLOT(new_connection(QString)));
    7. connect(m_socket,SIGNAL(readyRead()),this,SLOT(read()));
    8. m_socketDescriptor = m_socket->socketDescriptor();
    9.  
    10. emit address(m_socket->peerAddress().toString());
    11.  
    12. /* number of clients++ */
    13. m_parent->incNrClients();
    14.  
    15. nextBlockSize=0;
    16. }
    17.  
    18.  
    19. void Server_thread::run()
    20. {
    21. // just to keep the thread active...
    22. while(m_socket && m_socket->state() == QAbstractSocket::ConnectedState) {
    23.  
    24. }
    25.  
    26. m_socket->disconnectFromHost();
    27. m_socket->waitForDisconnected(1000);
    28. }
    29.  
    30. void Server_thread::read()
    31. {
    32. QDataStream in(m_socket);
    33. in.setVersion(QDataStream::Qt_4_2);
    34. /* read data */
    35. if(nextBlockSize==0) {
    36. if(m_socket->bytesAvailable() < sizeof(quint16))
    37. return;
    38.  
    39. in >> nextBlockSize;
    40. }
    41. if(m_socket->bytesAvailable() < nextBlockSize)
    42. return;
    43.  
    44. QString koordinate;
    45. int x1,y1,x2,y2;
    46.  
    47. in >> koordinate;
    48.  
    49. sscanf(koordinate.toStdString().c_str(),"%d %d %d %d",&x1,&y1,&x2,&y2);
    50.  
    51. m_parent->send(m_socketDescriptor,x1,y1,x2,y2);
    52. }
    53.  
    54. void Server_thread::send(int x1, int y1, int x2, int y2)
    55. {
    56. QString string;
    57. string += QString(to_string<int>(x1).c_str());
    58. string += " ";
    59. string += QString(to_string<int>(y1).c_str());
    60. string += " ";
    61. string += QString(to_string<int>(x2).c_str());
    62. string += " ";
    63. string += QString(to_string<int>(y2).c_str());
    64.  
    65.  
    66. QByteArray block;
    67. QDataStream out(&block, QIODevice::WriteOnly);
    68. out.setVersion(QDataStream::Qt_4_2);
    69. out << (quint16)0;
    70. out << string;
    71. out.device()->seek(0);
    72. out << (quint16)(block.size() - sizeof(quint16));
    73.  
    74. m_socket->write(block);
    75.  
    76. }
    To copy to clipboard, switch view to plain text mode 

    On the client side I have:
    Qt Code:
    1. using namespace irr;
    2. using namespace core;
    3. using namespace scene;
    4. using namespace video;
    5.  
    6. //event listener -> this works for sure
    7. class ChalkboardEventReceiver : public IEventReceiver
    8. {
    9. public:
    10. ChalkboardEventReceiver(Client *c)
    11. : mouseDown(false), connection(NULL)
    12. {
    13. connection = c;
    14. }
    15.  
    16. bool OnEvent(SEvent event)
    17. {
    18. if(event.EventType == EET_MOUSE_INPUT_EVENT) {
    19. if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
    20. x = event.MouseInput.X;
    21. y = event.MouseInput.Y;
    22. mouseDown = true;
    23.  
    24. return true;
    25. }
    26. else if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
    27. connection->AddLineLocal(x, y, event.MouseInput.X, event.MouseInput.Y);
    28. connection->SendLineToServer(x, y, event.MouseInput.X, event.MouseInput.Y);
    29. mouseDown = false;
    30.  
    31. return true;
    32. }
    33. else if(mouseDown && event.MouseInput.Event == EMIE_MOUSE_MOVED) {
    34. connection->AddLineLocal(x, y, event.MouseInput.X, event.MouseInput.Y);
    35. connection->SendLineToServer(x, y, event.MouseInput.X, event.MouseInput.Y);
    36. x = event.MouseInput.X;
    37. y = event.MouseInput.Y;
    38.  
    39. return true;
    40. }
    41. }
    42.  
    43. return false;
    44. }
    45.  
    46.  
    47. protected:
    48. s32 x, y;
    49. bool mouseDown;
    50. Client *connection;
    51. };
    52.  
    53. int main(int argc, char *argv[])
    54. {
    55. QApplication app(argc, argv);
    56.  
    57. Client client;
    58. ChalkboardEventReceiver receiver(&client);
    59. client.init(&receiver);
    60.  
    61. app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
    62. return app.exec();
    63.  
    64. }
    65.  
    66. Client::Client(QWidget *parent) : QWidget(parent)
    67. {
    68. connect(&m_socket, SIGNAL(readyRead()), this, SLOT(HandlePacket()));
    69. connect(&m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
    70. this, SLOT(displayError(QAbstractSocket::SocketError)));
    71. m_socket.connectToHost("127.0.0.1",3210);
    72. nextBlockSize = 0;
    73. // Wait for the init() call
    74. device = 0;
    75. // Default
    76. driverType = irr::video::EDT_OPENGL;
    77. }
    78.  
    79. void Client::SendLineToServer(s32 x1, s32 y1, s32 x2, s32 y2)
    80. {
    81.  
    82. QString string;
    83. string += QString(to_string<int>(x1).c_str());
    84. string += " ";
    85. string += QString(to_string<int>(y1).c_str());
    86. string += " ";
    87. string += QString(to_string<int>(x2).c_str());
    88. string += " ";
    89. string += QString(to_string<int>(y2).c_str());
    90.  
    91. QByteArray block;
    92. QDataStream out(&block, QIODevice::WriteOnly);
    93. out.setVersion(QDataStream::Qt_4_2);
    94. out << (quint16)0;
    95. out << string;
    96. out.device()->seek(0);
    97.  
    98. //calculate the size of the block
    99. out << (quint16)(block.size() - sizeof(quint16));
    100.  
    101. m_socket.write(block);
    102. }
    103.  
    104. void Client::HandlePacket()
    105. {
    106. QDataStream in(&m_socket);
    107. in.setVersion(QDataStream::Qt_4_2);
    108.  
    109. if (nextBlockSize == 0) {
    110. if (m_socket.bytesAvailable() < (int)sizeof(quint16))
    111. return;
    112.  
    113. in >> nextBlockSize;
    114. }
    115.  
    116. if (m_socket.bytesAvailable() < nextBlockSize)
    117. return;
    118.  
    119. QString string;
    120. in >> string;
    121.  
    122. s32 x1,y1,x2,y2;
    123. const char *str = string.toStdString().c_str();
    124. sscanf(str,"%d %d %d %d",&x1,&y1,&x2,&y2);
    125.  
    126. AddLineLocal(x1, y1, x2, y2);
    127. }
    To copy to clipboard, switch view to plain text mode 

    I'm sorry for posting so much code here (I attached the whole source code). I would really appreciate some help.
    Attached Files Attached Files

Similar Threads

  1. QT MySQL
    By sabeeshcs in forum Newbie
    Replies: 6
    Last Post: 12th January 2007, 04:19
  2. Reading from TCP Socket crashes program
    By OnionRingOfDoom in forum Qt Programming
    Replies: 26
    Last Post: 27th January 2006, 19:32

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
  •  
Qt is a trademark of The Qt Company.