Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QUdpSocket doesn't trigger readyread signal
Forum Updated to NodeBB v4.3 + New Features

QUdpSocket doesn't trigger readyread signal

Scheduled Pinned Locked Moved Unsolved General and Desktop
21 Posts 4 Posters 3.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Raffael Sakrenz
    wrote on last edited by
    #1

    Hello,
    I am using Qt 5.12.9.

    I am currently developing a service application, which shall receive udp packets from another application (not QT) running on the same PC.

    I create, bind and connect the slot of the socket like this:

    m_hmiSocket = new QUdpSocket(this);
    tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::Any, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
    
    tBool connectSuccess = QObject::connect(m_hmiSocket, SIGNAL(readyRead()), this, SLOT(OnUdpReceiveHmi()));
    

    In the slot function. I have a log call in the first line, but it doesn't get called. I once called the readyRead method manually and it called the slot function. I once tried the same connect call with the destroyed signal of QUdpSocket and after deleting the socket the function got called as well.

    So am I missing something or is this a QT bug?

    KroMignonK jsulmJ 2 Replies Last reply
    0
    • R Raffael Sakrenz

      Hello,
      I am using Qt 5.12.9.

      I am currently developing a service application, which shall receive udp packets from another application (not QT) running on the same PC.

      I create, bind and connect the slot of the socket like this:

      m_hmiSocket = new QUdpSocket(this);
      tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::Any, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
      
      tBool connectSuccess = QObject::connect(m_hmiSocket, SIGNAL(readyRead()), this, SLOT(OnUdpReceiveHmi()));
      

      In the slot function. I have a log call in the first line, but it doesn't get called. I once called the readyRead method manually and it called the slot function. I once tried the same connect call with the destroyed signal of QUdpSocket and after deleting the socket the function got called as well.

      So am I missing something or is this a QT bug?

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by
      #2

      @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

      In the slot function. I have a log call in the first line, but it doesn't get called. I once called the readyRead method manually and it called the slot function. I once tried the same connect call with the destroyed signal of QUdpSocket and after deleting the socket the function got called as well.
      So am I missing something or is this a QT bug?

      Have first check if bind was successful?

      tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::Any, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
      if(!boundState_hmi ) 
      {
          qDebug() << "UDP bind failure:" << m_hmiSocket->errorString();
      }
      

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      1 Reply Last reply
      1
      • R Raffael Sakrenz

        Hello,
        I am using Qt 5.12.9.

        I am currently developing a service application, which shall receive udp packets from another application (not QT) running on the same PC.

        I create, bind and connect the slot of the socket like this:

        m_hmiSocket = new QUdpSocket(this);
        tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::Any, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
        
        tBool connectSuccess = QObject::connect(m_hmiSocket, SIGNAL(readyRead()), this, SLOT(OnUdpReceiveHmi()));
        

        In the slot function. I have a log call in the first line, but it doesn't get called. I once called the readyRead method manually and it called the slot function. I once tried the same connect call with the destroyed signal of QUdpSocket and after deleting the socket the function got called as well.

        So am I missing something or is this a QT bug?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

        So am I missing something or is this a QT bug?

        The socket probably does not receive anything.
        You could use for example Wireshark to observe the network traffic.
        Also, what does bind() return?

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • R Offline
          R Offline
          Raffael Sakrenz
          wrote on last edited by
          #4

          Sorry, I forgot to give you the information which I already had..

          bind and connect both return true.

          I checked the packages on Wireshark. They are sent. Actually if the service is not running I get a "destination unreachable" info.
          fc6c9e3d-4a6c-4c02-a5ba-efaa075b6c31-grafik.png

          If the service is running I don't get that. So I assume that the port is opened correctly.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            Raffael Sakrenz
            wrote on last edited by
            #5

            81238f4a-b459-4db1-a139-8345eecc504f-grafik.png

            1 Reply Last reply
            0
            • R Offline
              R Offline
              Raffael Sakrenz
              wrote on last edited by
              #6

              When I triggered the readyRead() signal I was also able to read the datagram which was in that udp packet.

              1 Reply Last reply
              0
              • R Offline
                R Offline
                Raffael Sakrenz
                wrote on last edited by
                #7

                @jsulm, @KroMignon : No idea? Can you reproduce this issue?

                jsulmJ KroMignonK 2 Replies Last reply
                0
                • R Raffael Sakrenz

                  @jsulm, @KroMignon : No idea? Can you reproduce this issue?

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Raffael-Sakrenz You could try other ports and also disable firewall.

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • R Raffael Sakrenz

                    @jsulm, @KroMignon : No idea? Can you reproduce this issue?

                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by
                    #9

                    @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                    No idea? Can you reproduce this issue?

                    I am not aware about such an issue.
                    I am using QTcpSocket/QUdpSocket in many application with Windows/Linux/Android and it simply works.

                    According to WireShark capture, UPD diagramme are sent from port 59542 to port 2341.
                    Is 2341 the value of m_hmiPortIn?

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      Raffael Sakrenz
                      wrote on last edited by
                      #10

                      @KroMignon said in QUdpSocket doesn't trigger readyread signal:

                      2341

                      Yes it is. The weird thing is, that with an older QT version (4.7.1 or something like this) it worked. And again, if I trigger the readyRead signal, or if I stay in a while loop and read the pending datagrams, I get the information which has been sent already. Its just the readyRead signal which somehow doesn't get emitted....

                      Is there any other way to debug this? I will try another port, but I used the exact same port with qt4

                      KroMignonK 1 Reply Last reply
                      0
                      • R Raffael Sakrenz

                        @KroMignon said in QUdpSocket doesn't trigger readyread signal:

                        2341

                        Yes it is. The weird thing is, that with an older QT version (4.7.1 or something like this) it worked. And again, if I trigger the readyRead signal, or if I stay in a while loop and read the pending datagrams, I get the information which has been sent already. Its just the readyRead signal which somehow doesn't get emitted....

                        Is there any other way to debug this? I will try another port, but I used the exact same port with qt4

                        KroMignonK Offline
                        KroMignonK Offline
                        KroMignon
                        wrote on last edited by
                        #11

                        @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                        Is there any other way to debug this? I will try another port, but I used the exact same port with qt4

                        Okay, now I think I got it!
                        No, this is not a port number issue.

                        One thing to note, is that QUdpSocket emits readyRead() only for one datagram and that if you don't read it, the class will not emit again.
                        So you have to read all pending datagrams before next readyRead() can be emitted.

                        Something like:

                        void MyClass::OnUdpReceiveHmi()
                        {
                            while(m_hmiSocket->hasPendingDatagrams())
                            {
                                QByteArray buffer;
                                buffer.resize(m_hmiSocket->pendingDatagramSize());
                                QHostAddress sender;
                                quint16 senderPort;
                                m_hmiSocket->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort);
                                
                                 ....
                            }
                        }
                        

                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                        1 Reply Last reply
                        0
                        • R Offline
                          R Offline
                          Raffael Sakrenz
                          wrote on last edited by
                          #12

                          Hi @KroMignon :

                          Thanks for the reply. This is actually the code of my OnUdpReceiveHmi() method. Nevertheless if I didn't have had that code, the readyRead() signal should at least be emitted once, which isn't the case.

                          I once had a while loop right after the QObject::connect function like this:

                          while(!m_hmiSocket->hasPendingDatagrams())
                          {}
                          if (m_hmiSocket->hasPendingDatagrams())
                          	{
                          		QByteArray datagram;
                          		datagram.resize(m_hmiSocket->pendingDatagramSize());
                          		QHostAddress sender;
                          		quint16 senderPort;
                          
                          		m_hmiSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
                          
                          		LOG_INFO(QString("UDP packet received: ").append(datagram.data()).toStdString().c_str());
                          	}
                          

                          With that piece of code I was able to read the first incoming datagram but after that nothing happened again. Is there any other way to check if the signal gets emitted or is the QObject::connect function the only way to do it?

                          KroMignonK 1 Reply Last reply
                          0
                          • Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                            while(!m_hmiSocket->hasPendingDatagrams())
                            {}

                            Why? You block the event loop...

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            1 Reply Last reply
                            0
                            • R Raffael Sakrenz

                              Hi @KroMignon :

                              Thanks for the reply. This is actually the code of my OnUdpReceiveHmi() method. Nevertheless if I didn't have had that code, the readyRead() signal should at least be emitted once, which isn't the case.

                              I once had a while loop right after the QObject::connect function like this:

                              while(!m_hmiSocket->hasPendingDatagrams())
                              {}
                              if (m_hmiSocket->hasPendingDatagrams())
                              	{
                              		QByteArray datagram;
                              		datagram.resize(m_hmiSocket->pendingDatagramSize());
                              		QHostAddress sender;
                              		quint16 senderPort;
                              
                              		m_hmiSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
                              
                              		LOG_INFO(QString("UDP packet received: ").append(datagram.data()).toStdString().c_str());
                              	}
                              

                              With that piece of code I was able to read the first incoming datagram but after that nothing happened again. Is there any other way to check if the signal gets emitted or is the QObject::connect function the only way to do it?

                              KroMignonK Offline
                              KroMignonK Offline
                              KroMignon
                              wrote on last edited by
                              #14

                              @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                              while(!m_hmiSocket->hasPendingDatagrams())
                              {}
                              if (m_hmiSocket->hasPendingDatagrams())

                              This is a dangerous coding style!
                              Why do you do this?
                              Please change this to while(m_hmiSocket->hasPendingDatagrams()).

                              Other suggestion would be to change to bind statement to:

                              tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::Any, m_hmiPortIn, QAbstractSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
                              

                              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                              1 Reply Last reply
                              0
                              • R Offline
                                R Offline
                                Raffael Sakrenz
                                wrote on last edited by
                                #15

                                I just did this once, just to check whether datagrams are even arrived on the port. Just right after, I deleted the code again.

                                The change of the bind statement didn't change anything. My slot is still not being called.

                                KroMignonK 1 Reply Last reply
                                0
                                • Christian EhrlicherC Offline
                                  Christian EhrlicherC Offline
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                                  My slot is still not being called.

                                  Please show your complete code and make sure to not block the event loop. Also try the examples in the QUdpSocket documentation to see if they work for you.

                                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                  Visit the Qt Academy at https://academy.qt.io/catalog

                                  1 Reply Last reply
                                  0
                                  • R Raffael Sakrenz

                                    I just did this once, just to check whether datagrams are even arrived on the port. Just right after, I deleted the code again.

                                    The change of the bind statement didn't change anything. My slot is still not being called.

                                    KroMignonK Offline
                                    KroMignonK Offline
                                    KroMignon
                                    wrote on last edited by
                                    #17

                                    @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                                    The change of the bind statement didn't change anything. My slot is still not being called.

                                    Hmm, another idea I've got.
                                    According to your WireShark capture, the datagram are sent very often.
                                    Perhaps you should connect the readyRead() signal before doing the bind(), to avoid datagram reception before connection readyRead().

                                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                    1 Reply Last reply
                                    0
                                    • R Offline
                                      R Offline
                                      Raffael Sakrenz
                                      wrote on last edited by
                                      #18

                                      header

                                      class cRecordingService : public QObject, public object<cADTFService>
                                      {
                                      	Q_OBJECT
                                      public:
                                      	ADTF_CLASS_ID_NAME(cRecordingService, "recordingService.daq.service.cid", "Robert Bosch Recording Service");
                                      	ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(IKernel));
                                      
                                      	cRecordingService();
                                      	tResult ServiceEvent(tInt nEventId, tUInt32 ui32Param1 = 0, tUInt32 ui32Param2 = 0, tVoid* pvData = nullptr, tInt szData = 0) override;
                                      	tResult ServiceInit() override;
                                      	tResult ServiceShutdown() override;
                                      
                                      private:
                                      	// UDP
                                      	QUdpSocket* m_hmiSocket;
                                      	static const quint16 m_hmiPortIn = 2341;
                                      	static const quint16 m_hmiPortOut = 2340;
                                      public slots:
                                      	void OnUdpReceiveHmi();
                                      }
                                      

                                      cpp

                                      tResult cRecordingService::intializeUdpPort()
                                      {
                                      	// Initialization of the UDP socket
                                      	// First create the socket and bind it to the IP address and port on which the HMI sends its messages
                                      	m_hmiSocket = new QUdpSocket(this);
                                      	tBool connectSuccess = QObject::connect(m_hmiSocket, SIGNAL(readyRead()), this, SLOT(OnUdpReceiveHmi()));
                                      	LOG_INFO("### Recording-Tool-Service-Log: connect signal slot success: " + cString::FromType(connectSuccess));
                                      
                                      	tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::LocalHost, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
                                      	LOG_INFO("### Recording-Tool-Service-Log: Boundstate of HMI incoming socket: " + cString::FromType(boundState_hmi) + ", info:" + cString(m_hmiSocket->errorString().toStdString().c_str()));
                                      
                                      	
                                      
                                      	RETURN_NOERROR;
                                      }
                                      
                                      void cRecordingService::OnUdpReceiveHmi() {
                                      	LOG_INFO("### Recording-Tool-Service-Log: OnUdpReceiveHmi triggered!");
                                      	while (m_hmiSocket->hasPendingDatagrams())
                                      	{
                                      		QByteArray datagram;
                                      		datagram.resize(m_hmiSocket->pendingDatagramSize());
                                      		QHostAddress sender;
                                      		quint16 senderPort;
                                      
                                      		m_hmiSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
                                      
                                      		LOG_INFO(QString("UDP packet received: ").append(datagram.data()).toStdString().c_str());
                                      	}
                                      }
                                      
                                      The code is compiled as a service which runs inside an application. The event loop is not blocked because I tested the slot with another signal/event. I used the destroyed() signal, therefore I added at the end of "initializeUdpPort" delete m_hmiSocket to see if it works and it called directly the corresponding slot.
                                      
                                      KroMignonK 1 Reply Last reply
                                      0
                                      • R Raffael Sakrenz

                                        header

                                        class cRecordingService : public QObject, public object<cADTFService>
                                        {
                                        	Q_OBJECT
                                        public:
                                        	ADTF_CLASS_ID_NAME(cRecordingService, "recordingService.daq.service.cid", "Robert Bosch Recording Service");
                                        	ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(IKernel));
                                        
                                        	cRecordingService();
                                        	tResult ServiceEvent(tInt nEventId, tUInt32 ui32Param1 = 0, tUInt32 ui32Param2 = 0, tVoid* pvData = nullptr, tInt szData = 0) override;
                                        	tResult ServiceInit() override;
                                        	tResult ServiceShutdown() override;
                                        
                                        private:
                                        	// UDP
                                        	QUdpSocket* m_hmiSocket;
                                        	static const quint16 m_hmiPortIn = 2341;
                                        	static const quint16 m_hmiPortOut = 2340;
                                        public slots:
                                        	void OnUdpReceiveHmi();
                                        }
                                        

                                        cpp

                                        tResult cRecordingService::intializeUdpPort()
                                        {
                                        	// Initialization of the UDP socket
                                        	// First create the socket and bind it to the IP address and port on which the HMI sends its messages
                                        	m_hmiSocket = new QUdpSocket(this);
                                        	tBool connectSuccess = QObject::connect(m_hmiSocket, SIGNAL(readyRead()), this, SLOT(OnUdpReceiveHmi()));
                                        	LOG_INFO("### Recording-Tool-Service-Log: connect signal slot success: " + cString::FromType(connectSuccess));
                                        
                                        	tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::LocalHost, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
                                        	LOG_INFO("### Recording-Tool-Service-Log: Boundstate of HMI incoming socket: " + cString::FromType(boundState_hmi) + ", info:" + cString(m_hmiSocket->errorString().toStdString().c_str()));
                                        
                                        	
                                        
                                        	RETURN_NOERROR;
                                        }
                                        
                                        void cRecordingService::OnUdpReceiveHmi() {
                                        	LOG_INFO("### Recording-Tool-Service-Log: OnUdpReceiveHmi triggered!");
                                        	while (m_hmiSocket->hasPendingDatagrams())
                                        	{
                                        		QByteArray datagram;
                                        		datagram.resize(m_hmiSocket->pendingDatagramSize());
                                        		QHostAddress sender;
                                        		quint16 senderPort;
                                        
                                        		m_hmiSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
                                        
                                        		LOG_INFO(QString("UDP packet received: ").append(datagram.data()).toStdString().c_str());
                                        	}
                                        }
                                        
                                        The code is compiled as a service which runs inside an application. The event loop is not blocked because I tested the slot with another signal/event. I used the destroyed() signal, therefore I added at the end of "initializeUdpPort" delete m_hmiSocket to see if it works and it called directly the corresponding slot.
                                        
                                        KroMignonK Offline
                                        KroMignonK Offline
                                        KroMignon
                                        wrote on last edited by
                                        #19

                                        @Raffael-Sakrenz said in QUdpSocket doesn't trigger readyread signal:

                                        The code is compiled as a service which runs inside an application. The event loop is not blocked because I tested the slot with another signal/event. I used the destroyed() signal, therefore I added at the end of "initializeUdpPort" delete m_hmiSocket to see if it works and it called directly the corresponding slot.

                                        Your "event loop check" looks strange to me.
                                        Why not simply try with QTimer::signelShot()?
                                        Another thing, I would recommend you to use new connect syntax to enable connect check at compilation time:

                                        // Initialization of the UDP socket
                                        // First create the socket and bind it to the IP address and port on which the HMI sends its messages
                                        m_hmiSocket = new QUdpSocket(this);
                                        tBool connectSuccess = connect(m_hmiSocket, &QUdpSocket::readyRead, this, &cRecordingService::OnUdpReceiveHmi);
                                        LOG_INFO("### Recording-Tool-Service-Log: connect signal slot success: " + cString::FromType(connectSuccess));
                                        
                                        tBool boundState_hmi = m_hmiSocket->bind(QHostAddress::LocalHost, m_hmiPortIn, QUdpSocket::ReuseAddressHint);
                                        LOG_INFO("### Recording-Tool-Service-Log: Boundstate of HMI incoming socket: " + cString::FromType(boundState_hmi) + ", info:" + cString(m_hmiSocket->errorString().toStdString().c_str()));
                                        
                                        // Just for test purpose
                                        QTimer::singleShot(100, this, [this]() {
                                            qDebug() << "### Event loop is working :)." << (m_hmiSocket->hasPendingDatagrams() ? "PENDING DATAGRAM" : "NO DATAGRAM");
                                            });
                                        

                                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                        1 Reply Last reply
                                        0
                                        • R Offline
                                          R Offline
                                          Raffael Sakrenz
                                          wrote on last edited by
                                          #20

                                          @KroMignon
                                          I tested your suggestion. First there is no datagram but if I switch on my other (sending) application, the datagram is found.

                                          I also modified the code and made a cyclic timer, which reads every second the status and if there is a datagram also the datagram itself.

                                          In the end I read the datagram in that timer callback function instead of the slot. I don't understand it. Aren't you able to reproduce the issue?

                                          Is there any way, why the signal could be blocked from being sent? I read in the QT issue tracker, that the QSerialSocket had some issues with readyRead in 5.12....

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved