Results 1 to 5 of 5

Thread: Threaded TCP server

  1. #1
    Join Date
    Feb 2008
    Posts
    3
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Threaded TCP server

    Hello,

    I'm writing an application to view MRI Images sent over a TCP connection. My program works well in a single thread but the problems arise when I try to run the server part in a separate thread.

    I get the error "-1" when I try to set the descriptor of the socket :
    Qt Code:
    1. if (clientSocket->setSocketDescriptor(socketId))
    2. {
    3. emit error(clientSocket->error());
    4. cout << "setSocketDescriptor error : " << clientSocket->error() << endl;
    5. return;
    6. }
    To copy to clipboard, switch view to plain text mode 

    In the main window, I create a server object which starts listening :
    Qt Code:
    1. if (!server->listen(QHostAddress(QHostAddress::Any/*ipAddress*/), serverPort)) {
    2. cerr << "Failed to open bind port" << endl;
    3. }
    To copy to clipboard, switch view to plain text mode 

    Here is my implementation of the Server class :
    Qt Code:
    1. #include "server.h"
    2. #include "serverthread.h"
    3. #include <iostream>
    4.  
    5. using namespace std;
    6.  
    7. Server::Server(QObject *parent)
    8. : QTcpServer(parent)
    9. {
    10. }
    11.  
    12.  
    13. void Server::incomingConnection(int socketId)
    14. {
    15. cout << " socketID : " << socketId << endl;
    16. ServerThread *serverThread = new ServerThread(socketId, NULL);
    17. connect(serverThread, SIGNAL(finished()), serverThread, SLOT(deleteLater()));
    18. emit clientConnected();
    19. serverThread->start();
    20. }
    To copy to clipboard, switch view to plain text mode 

    The code of the ServerThread class :
    Qt Code:
    1. #include "serverthread.h"
    2. #include "clientsocket.h"
    3. #include <QtNetwork>
    4. #include <iostream>
    5.  
    6. using namespace std;
    7.  
    8. ServerThread::ServerThread(int socketDescriptor, QObject *parent)
    9. : QThread(parent), socketId(socketId)
    10. {
    11. socketId = socketDescriptor;
    12. }
    13.  
    14. void ServerThread::run()
    15. {
    16. cout << " socketID 2 : " << socketId << endl;
    17. ClientSocket *clientSocket = new ClientSocket(/*this*/NULL);
    18. if (clientSocket->setSocketDescriptor(socketId)) {
    19. emit error(clientSocket->error());
    20. cout << "setSocketDescriptor error : " << clientSocket->error() << endl;
    21. return;
    22. }
    23. }
    To copy to clipboard, switch view to plain text mode 

    And finally the ClientSocket class :
    Qt Code:
    1. #include <QtNetwork>
    2. #include <cstdlib>
    3. #include <iostream>
    4.  
    5. #include "clientsocket.h"
    6.  
    7. using namespace std;
    8.  
    9. ClientSocket::ClientSocket(QObject *parent)
    10. : QTcpSocket(parent)
    11. {
    12. connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));
    13. connect(this, SIGNAL(error(QAbstractSocket::SocketError)),
    14. this, SLOT(displayError(QAbstractSocket::SocketError)));
    15. connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
    16. }
    17.  
    18. void ClientSocket::readClient()
    19. {
    20. QFile dumpFile("/home/meylan/QT/IRMServer/dump.log");
    21. dumpFile.open(QIODevice::WriteOnly);
    22. QDataStream dump(&dumpFile);
    23. QDataStream in(this);
    24. qint64 bytesDispo;
    25. qint8 data;
    26.  
    27. in.setVersion(QDataStream::Qt_4_1);
    28.  
    29. while (this->waitForReadyRead(500)) {
    30. bytesDispo = this->bytesAvailable();
    31. cout << endl << "Taille du paquet : " << bytesDispo << endl;
    32. for (int i = 0; i < bytesDispo; i++) {
    33. in >> data;
    34. dump << data;
    35. }
    36. }
    37. dumpFile.close();
    38. close();
    39. }
    40.  
    41. void ClientSocket::displayError(QAbstractSocket::SocketError socketError)
    42. {
    43. switch (socketError) {
    44. case QAbstractSocket::RemoteHostClosedError:
    45. cout << "Remote host closed !" << endl;
    46. break;
    47. case QAbstractSocket::HostNotFoundError:
    48. cout <<"Host not found !" << endl;
    49. break;
    50. case QAbstractSocket::ConnectionRefusedError:
    51. cout << "Connection refused !" << endl;
    52. break;
    53. default:
    54. cout << this->error() << endl;
    55. }
    56. }
    To copy to clipboard, switch view to plain text mode 

    Do you have any idea of what I'm doing wrong ?

    Thanks in advance for your help.

  2. The following user says thank you to Sysace for this useful post:

    Suncell (6th June 2010)

  3. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Threaded TCP server

    Hello,

    Quoting QAbstractSocket::setSockerDescriptor() docs:
    Returns true if socketDescriptor is accepted as a valid socket descriptor; otherwise returns false.
    So I guess it should be:
    Qt Code:
    1. if (!clientSocket->setSocketDescriptor(socketId))
    2. {
    3. ...
    4. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  4. #3
    Join Date
    Feb 2008
    Posts
    3
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Threaded TCP server

    Thank you for your quick reply !

    Damn, you're absolutely right, I don't know who has eaten that "!"

    Still, the problem remains, as I cannot receive the data transferred. My program seems to act as if the readyRead signal was not emitted. I guess the problem is related to the way I coded the thread since the same code works with only one thread (in this case there is no ServerThread class and the clientSocket is created in the server class).

    By the way, I had to replace this by NULL here :

    Qt Code:
    1. ClientSocket *clientSocket = new ClientSocket(/*this*/NULL);
    To copy to clipboard, switch view to plain text mode 

    to avoid the Cannot create children for a parent that is in a different thread. error. I guess this is not the correct way to avoid the problem...

    Can you tell me if my way of creating the thread is the good one ?

    I will check the entire code again to try to figure what makes the difference between the working single thread code and this one.

    Thank you very much.

    Best regards.

  5. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Threaded TCP server

    ServerThread::run() should look more or less something like this:
    Qt Code:
    1. void ServerThread::run()
    2. {
    3. cout << " socketID 2 : " << socketId << endl;
    4. ClientSocket clientSocket; // <-- exec() blocks so it's ok to allocate on the stack
    5. if (!clientSocket.setSocketDescriptor(socketId)) {
    6. emit error(clientSocket.error());
    7. cout << "setSocketDescriptor error : " << clientSocket.error() << endl;
    8. return;
    9. }
    10. exec(); // <-- enter to the event loop
    11. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  6. The following 2 users say thank you to jpn for this useful post:

    Suncell (6th June 2010), Sysace (21st February 2008)

  7. #5
    Join Date
    Feb 2008
    Posts
    3
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Threaded TCP server

    Thank you for your help.

    The cause of the error was the missing
    Qt Code:
    1. exec();
    To copy to clipboard, switch view to plain text mode 
    instruction.

    Best regards.

Similar Threads

  1. Threaded server.
    By nithinin2001 in forum Qt Programming
    Replies: 2
    Last Post: 15th November 2007, 16:37
  2. How to download any file through ftp server
    By thomasjoy in forum Qt Programming
    Replies: 1
    Last Post: 24th July 2007, 01:23
  3. How to ping a server ?
    By Nyphel in forum Newbie
    Replies: 2
    Last Post: 23rd April 2007, 11:27
  4. How a server can write "Hello" to a browser ?
    By probine in forum Qt Programming
    Replies: 2
    Last Post: 1st December 2006, 14:43
  5. synching client readings to server output
    By OnionRingOfDoom in forum Qt Programming
    Replies: 14
    Last Post: 28th January 2006, 18:15

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.