Results 1 to 10 of 10

Thread: Signal never received from network capture thread

  1. #1
    Join Date
    Jul 2009
    Location
    France
    Posts
    17
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Unhappy Signal never received from network capture thread

    Hi,

    My (sniffer) appliation has a capture QThread which is awaiting packets from a network interface and shall emit then this received packet to the main (GUI) thread for edicated treatment.
    My problem is that emit is called but signal is never received by the client class which which was connected to this signal the main thread.

    1 - Any idea why this does not work ?
    2 - Can the client class connect to the QThread BEFORE the tread has been started (before call to start()) ?

    Thanks.

    Note:
    The sniffer thread uses pcap library for low level sniffing.

    Here below is the simplified code to give an idea of the implementation :

    Qt Code:
    1. class SnifferThread : public QThread
    2. {
    3. Q_OBJECT;
    4.  
    5. signals:
    6. void signalPacketReceived(uint8* pData, uint32 pDataLength, uint32 pOrd);
    7. //...
    8. };
    9.  
    10. void SnifferThread::run()
    11. {
    12. pcapfp_ = pcap_open_live(itf.c_str(), PCAP_MAX_NB_BYTE, 1, -1, errorBuffer);
    13. pcap_pkthdr pktHeader;
    14.  
    15. while (canSniff_)
    16. {
    17. isSniffing_ = true;
    18.  
    19. const uint8* data = pcap_next(pcapfp_, &pktHeader);
    20. if ( data != 0 )
    21. {
    22. // ...
    23. emit signalPacketReceived(buffer, bufSize, ++frameNumber_);
    24. }
    25. else
    26. {
    27. // No packet available: very short asleep
    28. QThread::msleep(20);
    29. }
    30. }
    31. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    My problem is that emit is called but signal is never received by the client class which which was connected to this signal the main thread.
    A common issue is typos in the connect() line.
    Do you get a connect() no such signal/slot warning while building?

    2 - Can the client class connect to the QThread BEFORE the tread has been started (before call to start()) ?
    If you have the addresses of the emitting and receiving objects, you can connect them at any time.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Jul 2009
    Location
    France
    Posts
    17
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    I use to always check the return code of connect() with an assertion and it is OK : client successfuly connect to the sniffer thread signal.

    Qt Code:
    1. bool ok = connect(...)
    2. assert(ok == true);
    To copy to clipboard, switch view to plain text mode 

    Is there a way to go in debug mode inside Qt so that we can see the event queue state/length at the emetter side (my sniffer thread) ?

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    Is there a way to go in debug mode inside Qt so that we can see the event queue state/length at the emetter side (my sniffer thread) ?
    Yes, if you link against the debug Qt build.

    Are you using queued signals?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Jul 2009
    Location
    France
    Posts
    17
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    Yes, I use debug libs for Qt.
    I do not specify anything about signal/slot : just connect as usual (connect() without last parameter, so 'automatic'), assuming qt detects it shall be queued.

  6. #6
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    Standard receipt 1787453685 : try to add betwen lines 29 and 30 (at the end of loop)
    Qt Code:
    1. QCoreApplication::processEvents();
    To copy to clipboard, switch view to plain text mode 
    Because (I think) sender and receiver of signal are in separeted threads so signala are queued. In line 23 the signal is put in queue. Then the signal is received to slot by event dispatcher, but You don't give them chance to do it by going around in while loop. It will be better to don't use while loop in SnifferThread::run() method but make only one prob to read data and call them by QTimer.
    P.S.
    Did You run somewhere SnifferThread::exec() method ?

  7. #7
    Join Date
    Jul 2009
    Location
    France
    Posts
    17
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    No nowhere I execute exec() method.
    Using QCoreApplication:rocessEvents(); inside main loop does not change anyhing.

  8. #8
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Signal never received from network capture thread

    Quote Originally Posted by skimpax View Post
    No nowhere I execute exec() method.
    I think that this is a source of Yours problem. Quotation from QThread doc : Enters the event loop and waits until exit() is called, returning the value that was passed to exit(). The value returned is 0 if exit() is called via quit().
    It is necessary to call this function to start event handling.
    So Yours class must look something like this :
    Qt Code:
    1. class SnifferThread : public QThread
    2. {
    3. Q_OBJECT;
    4.  
    5. signals:
    6. void signalPacketReceived(uint8* pData, uint32 pDataLength, uint32 pOrd);
    7. slots:
    8. void sniffOnePacket();
    9. //...
    10. private:
    11. QTimer m_timer;
    12. };
    13.  
    14. void SnifferThread::run()
    15. {
    16. pcapfp_ = pcap_open_live(itf.c_str(), PCAP_MAX_NB_BYTE, 1, -1, errorBuffer);
    17. connect(&m_timer,SIGNAL(timeout()),this,SLOT(sniffOnePacket()));
    18. m_timer.start(20);
    19. exec();
    20. disconnect(&m_timer,SIGNAL(timeout()),this,SLOT(sniffOnePacket()));
    21. }
    22.  
    23. void SnifferThread::sniffOnePacket()
    24. {
    25. pcap_pkthdr pktHeader;
    26.  
    27. if(canSniff_)
    28. {
    29. isSniffing_ = true;
    30.  
    31. const uint8* data = pcap_next(pcapfp_, &pktHeader);
    32. if ( data != 0 )
    33. {
    34. // ...
    35. emit signalPacketReceived(buffer, bufSize, ++frameNumber_);
    36. }
    37. }
    38. }
    To copy to clipboard, switch view to plain text mode 
    This code is not tested.

  9. The following user says thank you to Lesiok for this useful post:

    skimpax (2nd February 2010)

  10. #9
    Join Date
    Jul 2009
    Location
    France
    Posts
    17
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Talking Re: Signal never received from network capture thread

    I also understood my error was that I never call QThread::exec().

    I changed my implementation to delegate sniffing activity to a dedicated class.
    In my SniffferThread::run(), I just instanciate this SnifferCore object and send it the start signal, then QThread::start() goes in exec().

    The main difference between our both implementation is that you rely on a timer, while I use QCoreApplication:rocessevents() to let the Qt event loop processing.

    Your proposal is very interesting : I will check the avantages of each to do my final implementation.

    Qt Code:
    1. void SnifferThread::run()
    2. {
    3. if ( core_ == 0 )
    4. {
    5. core_ = new SnifferCore(this);
    6. }
    7.  
    8. emit signalAction(true);
    9. exec();
    10. }
    11.  
    12. void SnifferCore::slotAction(bool pStart)
    13. {
    14. if ( pStart )
    15. {
    16. openDeviceNetwork();
    17. pcap_pkthdr pktHeader;
    18.  
    19. while (canSniff_)
    20. {
    21. isSniffing_ = true;
    22.  
    23. // Handle pause case
    24. bool first = true;
    25. while (canSniff_ )
    26. {
    27. const uint8* data = pcap_next(pcapfp_, &pktHeader);
    28. if ( data != 0 )
    29. {
    30. emit signalPacketReceived(data , ...);
    31. }
    32. else
    33. {
    34. // No packet available: very short asleep
    35. QCoreApplication::processEvents();
    36. }
    37. }
    38. )
    39.  
    40. cleanup();
    41. }
    To copy to clipboard, switch view to plain text mode 

    Many thanks

  11. #10
    Join Date
    Jul 2009
    Location
    France
    Posts
    17
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Exclamation Re: Signal never received from network capture thread

    Reply to myself as I lost a lot of time to understand why my reworked implementation did not work:

    I reworked my test code above by replacing :
    Qt Code:
    1. void SnifferCore::slotAction(bool pStart);
    To copy to clipboard, switch view to plain text mode 
    by something like :
    Qt Code:
    1. typedef enum
    2. {
    3. ActStart,
    4. ActStop
    5. } Action_e;
    6. void SnifferCore::slotAction(Action_e pAction);
    To copy to clipboard, switch view to plain text mode 
    The connection was OK, but the slot slotAction(Action_e) was never called at runtime !!!
    I put back a bool instead... and it work !!!
    I used an uint32 parameter (which is a #define of unsigned int) and it did not work.
    I used an int instead and it work.

    The key point is to use qRegisterMetaType

    Just by adding the line : qRegisterMetaType<Action_e>("Action_e"); things are OK.
    Qt Code:
    1. qRegisterMetaType<Action_e>("Action_e");
    2. ok = connect(myThread_, SIGNAL(signalAction(Action_e)),
    3. this, SLOT(slotAction(Action_e)));
    4. ASSERT(ok == true);
    To copy to clipboard, switch view to plain text mode 

    For any other people, if you have problem with queued signal/slot, don't forget, if you are using non-native type as parameter, to invoque qRegisterMetaType<YourType>("YourType"); before connecting !!!

    So many time lost , but so many learnt on Qt ...

Similar Threads

  1. Replies: 9
    Last Post: 28th November 2009, 20:31
  2. Replies: 3
    Last Post: 5th July 2009, 17:22
  3. Close a thread with a signal
    By victor374 in forum Qt Programming
    Replies: 1
    Last Post: 30th November 2007, 06:33
  4. Network programming and the main thread
    By invictus in forum Qt Programming
    Replies: 5
    Last Post: 16th March 2007, 00:25
  5. QSocket - signal for network wire disconnection
    By manivannan_1984 in forum Qt Programming
    Replies: 7
    Last Post: 5th September 2006, 13:52

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.