Results 1 to 8 of 8

Thread: Do i have to inherit from QTcpServer?

  1. #1
    Join Date
    Jun 2011
    Posts
    4
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question Do i have to inherit from QTcpServer?

    Hi,

    I’m trying to create a threaded server and in every example I saw someone creates a server by inheriting from QTcpServer. So I wonder, do I have to? I mean, you inherit only if you want to extend the class.

    Here is the class:
    myserver.h
    Qt Code:
    1. #ifndef MYSERVER_H
    2. #define MYSERVER_H
    3.  
    4. #include <QObject>
    5. #include <QtNetwork/QTcpServer>
    6. #include <QtConcurrentRun>
    7. #include <QFuture>
    8. #include "myclienthandle.h"
    9.  
    10. class MyServer : public QObject
    11. {
    12. Q_OBJECT
    13. public:
    14. explicit MyServer(QObject *parent = 0, const QString &ip = "Any", int port = 0);
    15. explicit MyServer(const MyServer &server);
    16. ~MyServer();
    17. QString IP() const;
    18. void setIP(const QString &ip);
    19. int Port() const;
    20. void setPort(int port);
    21. bool isAlive() const;
    22.  
    23.  
    24. private:
    25. QTcpServer *m_qtcpserListener;
    26. QFuture<void> m_qftrRun;
    27. QString *m_qstrIP;
    28. int m_iPort;
    29. int m_iClientID;
    30. bool m_bRun;
    31.  
    32. void run();
    33.  
    34. signals:
    35. void newConnection(MyClientHandle *clientHandle);
    36.  
    37. public slots:
    38. void start();
    39. void stop();
    40. };
    41.  
    42. inline QString MyServer::IP() const
    43. {
    44. return *m_qstrIP;
    45. }
    46.  
    47. inline void MyServer::setIP(const QString &ip)
    48. {
    49. m_qstrIP = new QString(ip);
    50. }
    51.  
    52. inline int MyServer::Port() const
    53. {
    54. return m_iPort;
    55. }
    56.  
    57. inline void MyServer::setPort(int port)
    58. {
    59. m_iPort = port;
    60. }
    61.  
    62. inline bool MyServer::isAlive() const
    63. {
    64. return m_bRun;
    65. }
    66.  
    67. #endif // MYSERVER_H
    To copy to clipboard, switch view to plain text mode 

    myserver.cpp
    Qt Code:
    1. #include "myserver.h"
    2.  
    3. MyServer::MyServer(QObject *parent, const QString &ip, int port) :
    4. QObject(parent), m_iClientID(0), m_bRun(false)
    5. {
    6. setIP(ip);
    7. setPort(port);
    8. }
    9.  
    10. MyServer::MyServer(const MyServer &server)
    11. {
    12. MyServer(server.parent(), server.IP(), server.Port());
    13. }
    14.  
    15. MyServer::~MyServer()
    16. {
    17. stop();
    18. }
    19.  
    20. void MyServer::run()
    21. {
    22. m_qtcpserListener = new QTcpServer(this);
    23.  
    24. if (!m_qtcpserListener->listen(QHostAddress(IP()), Port()))
    25. {
    26. return;
    27. }
    28.  
    29. while (m_bRun)
    30. {
    31. QTcpSocket *qtcpsoNextPending = m_qtcpserListener->nextPendingConnection();
    32. if(qtcpsoNextPending != 0)
    33. {
    34. emit newConnection(new MyClientHandle(qtcpsoNextPending));
    35. }
    36. }
    37. }
    38.  
    39. void MyServer::start()
    40. {
    41. m_bRun = true;
    42. m_qftrRun = QtConcurrent::run(this, &MyServer::run);
    43. }
    44.  
    45. void MyServer::stop()
    46. {
    47. m_bRun = false;
    48. if (m_qtcpserListener->isListening())
    49. {
    50. m_qtcpserListener->close();
    51. }
    52. }
    To copy to clipboard, switch view to plain text mode 

    Greats p.kreker
    Last edited by p.kreker; 16th June 2011 at 13:44.

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Do i have to inherit from QTcpServer?

    You should be able to implement with out inheriting QTcpServer, are you having any problem with it?

    Just some thought, you are creating QTcpServer in the context on new thread, so the parent cannot be "this" as it was created in the main thread context.

  3. The following user says thank you to Santosh Reddy for this useful post:

    p.kreker (27th June 2011)

  4. #3
    Join Date
    Jun 2011
    Posts
    8
    Thanked 3 Times in 3 Posts
    Qt products
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: Do i have to inherit from QTcpServer?

    inheriting is the strongest coupling, so don't use it if you has another option.

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

    p.kreker (27th June 2011)

  6. #4
    Join Date
    Jun 2011
    Posts
    4
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Do i have to inherit from QTcpServer?

    Okay... I had doubts whether I'm doing it right. I think the Qt documentation confuses more than it helps.

    I've moved the QTcpServer in an extra thread... This way was easier.

    Here's the final version of the MyServer class:

    myserver.h
    Qt Code:
    1. #ifndef MYSERVER_H
    2. #define MYSERVER_H
    3.  
    4. #include <QObject>
    5. #include <QtNetwork/QTcpServer>
    6. #include "myclienthandle.h"
    7.  
    8. class MyServer : public QObject
    9. {
    10. Q_OBJECT
    11. public:
    12. explicit MyServer(const QHostAddress &address = QHostAddress::Any, unsigned short port = 0, QObject *parent = 0);
    13. explicit MyServer(const MyServer &server);
    14. ~MyServer();
    15. QHostAddress Address() const;
    16. void setAddress(const QHostAddress &address);
    17. unsigned short Port() const;
    18. void setPort(unsigned short port);
    19. bool isRunning() const;
    20.  
    21.  
    22. private:
    23. QTcpServer *m_qtcpserListener;
    24. QHostAddress *m_qhaddAddress;
    25. QThread *m_qthServer;
    26. unsigned short m_iPort;
    27. bool m_bRunning;
    28.  
    29. void init(const QHostAddress &address, unsigned short port);
    30.  
    31. signals:
    32. void clientConnected(int socketDescriptor);
    33. void startError();
    34.  
    35. public slots:
    36. void start();
    37. void stop();
    38. void m_qtcpserListener_newConnection();
    39. };
    40.  
    41. inline QHostAddress MyServer::Address() const
    42. {
    43. return *m_qhaddAddress;
    44. }
    45.  
    46. inline void MyServer::setAddress(const QHostAddress &address)
    47. {
    48. m_qhaddAddress = new QHostAddress(address);
    49. }
    50.  
    51. inline unsigned short MyServer::Port() const
    52. {
    53. return m_iPort;
    54. }
    55.  
    56. inline void MyServer::setPort(unsigned short port)
    57. {
    58. m_iPort = port;
    59. }
    60.  
    61. inline bool MyServer::isRunning() const
    62. {
    63. return m_bRunning;
    64. }
    65.  
    66. inline void MyServer::m_qtcpserListener_newConnection()
    67. {
    68. emit clientConnected(m_qtcpserListener->nextPendingConnection()->socketDescriptor());
    69. }
    70.  
    71. #endif // MYSERVER_H
    To copy to clipboard, switch view to plain text mode 

    myserver.cpp
    Qt Code:
    1. #include "myserver.h"
    2.  
    3. MyServer::MyServer(const QHostAddress &address, unsigned short port, QObject *parent) :
    4. QObject(parent), m_bRunning(false)
    5. {
    6. init(address, port);
    7. }
    8.  
    9. MyServer::MyServer(const MyServer &server) :
    10. QObject(server.parent()), m_bRunning(false)
    11. {
    12. init(server.Address(), server.Port());
    13. }
    14.  
    15. MyServer::~MyServer()
    16. {
    17. stop();
    18. delete m_qtcpserListener;
    19. delete m_qthServer;
    20. }
    21.  
    22. void MyServer::init(const QHostAddress &address, unsigned short port)
    23. {
    24. m_qtcpserListener = new QTcpServer;
    25. m_qthServer = new QThread(this);
    26. setAddress(address);
    27. setPort(port);
    28.  
    29. connect(m_qtcpserListener, SIGNAL(newConnection()),
    30. this, SLOT(m_qtcpserListener_newConnection()),
    31. Qt::DirectConnection);
    32.  
    33. m_qtcpserListener->moveToThread(m_qthServer);
    34. }
    35.  
    36. void MyServer::start()
    37. {
    38. m_qtcpserListener->thread()->start();
    39. m_qtcpserListener->thread()->setObjectName(tr("Listeners Thread"));
    40. if (!m_qtcpserListener->listen(Address(), Port()))
    41. {
    42. stop();
    43. emit startError();
    44. } else {
    45. m_bRunning = true;
    46. }
    47. }
    48.  
    49. void MyServer::stop()
    50. {
    51. m_bRunning = false;
    52. if (m_qtcpserListener->isListening())
    53. {
    54. m_qtcpserListener->close();
    55. }
    56. m_qtcpserListener->thread()->quit();
    57. m_qtcpserListener->thread()->wait();
    58. }
    To copy to clipboard, switch view to plain text mode 

  7. #5
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Do i have to inherit from QTcpServer?

    This looks ok, is this working for you?

  8. #6
    Join Date
    Jun 2011
    Posts
    4
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Do i have to inherit from QTcpServer?

    Yes it works fine

    Edit 1:
    But I get this debug message:
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QTcpServer(0x1e3f6c8), parent's thread is QThread(0x1e3f9b0), current thread is QThread(0x1e37a40)
    At this command in the listen methode of m_qtcpserListener:
    Qt Code:
    1. bool QTcpServer::listen(const QHostAddress &address, quint16 port)
    2. {
    3. ...
    4. d->socketEngine = QAbstractSocketEngine::createSocketEngine(QAbstractSocket::TcpSocket, proxy, this);
    5. ...
    6. }
    To copy to clipboard, switch view to plain text mode 

    Why is the current thread in this methode different then the m_qtcpserListener thread? I mean, I've moved the m_qtcpserListener to an other thread, so the methodes should be executed in this thread or am I wrong?
    Last edited by p.kreker; 28th June 2011 at 09:52.

  9. #7
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Do i have to inherit from QTcpServer?

    QTcpServer::listen() is called from MyServer::start(), MyServer::start() runs in the context of the first / main thread, and you have already moved QTcpServer to new thread

    So move QTcpServer to new thread after QTcpServer::listen(), may be as last statement in MyServer::start()

  10. The following user says thank you to Santosh Reddy for this useful post:

    p.kreker (28th June 2011)

  11. #8
    Join Date
    Jun 2011
    Posts
    4
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Do i have to inherit from QTcpServer?

    Learing never stops

    Now the server works perfect

Similar Threads

  1. How can we inherit ui?
    By vinayaka in forum Newbie
    Replies: 5
    Last Post: 30th May 2011, 14:28
  2. About inherit
    By nesson in forum Qt Programming
    Replies: 1
    Last Post: 8th February 2011, 13:07
  3. Inherit from QTabWidget
    By Suncell in forum Newbie
    Replies: 2
    Last Post: 27th June 2010, 21:06
  4. How to use the ui_*.h,inherit it or as a member?
    By 75543255 in forum Qt Programming
    Replies: 1
    Last Post: 30th August 2009, 10:45
  5. Replies: 1
    Last Post: 18th June 2006, 10:12

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.