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 and broadcast receiver
Forum Updated to NodeBB v4.3 + New Features

QUdpSocket and broadcast receiver

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 6 Posters 1.9k Views 2 Watching
  • 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.
  • M Offline
    M Offline
    mrdebug
    wrote on 25 Nov 2021, 16:29 last edited by
    #1

    Hi, These lines of code

        QUSServer= new QUdpSocket(this);
        QUSServer->bind(3702, QAbstractSocket::DontShareAddress | QAbstractSocket::ReuseAddressHint);
        connect(QUSServer, SIGNAL(readyRead()), this, SLOT(DiscoveringPendingDatagrams()));
    
    

    should permit to receive broadcast udp packets.
    The problem is that the lines of code work only in a Windows machine but non in a Linux machine.
    In other words the signal readyRead() is fired only in Windows but not Linux.
    Have you got experience with QUdpSocket object?

    Need programmers to hire?
    www.labcsp.com
    www.denisgottardello.it
    GMT+1
    Skype: mrdebug

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 25 Nov 2021, 16:43 last edited by
      #2

      I don't see why these options should disallow receiving broadcasts.

      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
      • V Offline
        V Offline
        VRonin
        wrote on 25 Nov 2021, 16:44 last edited by
        #3

        QUdpSocket::bind returns a boolean to check if it worked or not and you can use QUdpSocket::errorString to inspect what went wrong

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        2
        • S Offline
          S Offline
          SHLEE
          wrote on 30 Nov 2021, 04:42 last edited by
          #4

          I had a same problem but, solved with following code.
          Try this.

          QUdpSocket* socket = new QUdpSocket();
          socket->bind(QHostAddress("255.255.255.255"), port);
          
          A K 2 Replies Last reply 30 Nov 2021, 10:38
          0
          • S SHLEE
            30 Nov 2021, 04:42

            I had a same problem but, solved with following code.
            Try this.

            QUdpSocket* socket = new QUdpSocket();
            socket->bind(QHostAddress("255.255.255.255"), port);
            
            A Offline
            A Offline
            artwaw
            wrote on 30 Nov 2021, 10:38 last edited by
            #5

            @SHLEE That assumes that the broadcast address is indeed 255.255.255.255. Which might not be true.

            For more information please re-read.

            Kind Regards,
            Artur

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SHLEE
              wrote on 30 Nov 2021, 11:51 last edited by SHLEE
              #6

              @artwaw I modified my source and test with wireshark today. I am reading books to know why it works. I ask you to just try it.

              1 Reply Last reply
              0
              • S SHLEE
                30 Nov 2021, 04:42

                I had a same problem but, solved with following code.
                Try this.

                QUdpSocket* socket = new QUdpSocket();
                socket->bind(QHostAddress("255.255.255.255"), port);
                
                K Offline
                K Offline
                KroMignon
                wrote on 30 Nov 2021, 19:31 last edited by
                #7

                @SHLEE said in QUdpSocket and broadcast receiver:

                socket->bind(QHostAddress("255.255.255.255"), port);

                This looks strange to me, this is the broadcast IP, you should better use 0.0.0.0 which is any IP.

                I guess the problem is not with the IP, I guess the UDP port is already in use.

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

                S 1 Reply Last reply 1 Dec 2021, 03:01
                0
                • K KroMignon
                  30 Nov 2021, 19:31

                  @SHLEE said in QUdpSocket and broadcast receiver:

                  socket->bind(QHostAddress("255.255.255.255"), port);

                  This looks strange to me, this is the broadcast IP, you should better use 0.0.0.0 which is any IP.

                  I guess the problem is not with the IP, I guess the UDP port is already in use.

                  S Offline
                  S Offline
                  SHLEE
                  wrote on 1 Dec 2021, 03:01 last edited by SHLEE 12 Jan 2021, 03:04
                  #8

                  @artwaw @KroMignon It is strange to me too but, it is true that it works on linux device.
                  Qt version is 4.8. It is not lastest but I think it doesn't matter.
                  This is test source. I talked all my experience and it's up to you. Good luck.

                  mainwindow.h

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  
                  #include <QList>
                  
                  QT_BEGIN_NAMESPACE
                  class QUdpSocket;
                  QT_END_NAMESPACE
                  
                  namespace Ui {
                  class MainWindow;
                  }
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                      
                  public:
                      explicit MainWindow(QWidget *parent = 0);
                      ~MainWindow();
                      
                  private:
                      Ui::MainWindow *ui;
                      QList<QUdpSocket*> m_sendSockets;
                      QList<QUdpSocket*> m_recvSockets;
                  
                  private slots:
                      void onPushButtonBroadcastClicked();
                      void onLocalIpSocketReadyToRead();
                      void onBroadcastIpSocketReadyToRead();
                  };
                  
                  #endif // MAINWINDOW_H
                  

                  mainwindow.cpp

                  #include "mainwindow.h"
                  #include "ui_mainwindow.h"
                  
                  #include <QUdpSocket>
                  #include <QHostAddress>
                  #include <QNetworkInterface>
                  
                  const int sendPort = 10000;
                  const int recvPort = 12345;
                  
                  MainWindow::MainWindow(QWidget *parent) :
                      QMainWindow(parent),
                      ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                  
                      connect(ui->pushButtonBroadcast, SIGNAL(clicked()), this, SLOT(onPushButtonBroadcastClicked()));
                  
                      QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
                      QUdpSocket* socket = NULL;
                  
                      while (addresses.count() > 0) {
                          QHostAddress address = addresses.takeFirst();
                          if (address.isNull()) {
                              continue;
                          }
                  
                          // sender
                          socket = new QUdpSocket(this);
                          if (socket->bind(address, sendPort)) {
                              m_sendSockets << socket;
                          } else {
                              delete socket;
                              continue;
                          }
                  
                          // receiver
                          socket = new QUdpSocket(this);
                          if (socket->bind(address, recvPort)) {
                              m_recvSockets << socket;
                              connect(socket, SIGNAL(readyRead()), this, SLOT(onLocalIpSocketReadyToRead()));
                          } else {
                              delete socket;
                              continue;
                          }
                      }
                  
                      socket = new QUdpSocket(this);
                      if (socket->bind(QHostAddress("255.255.255.255"), recvPort)) {
                          m_recvSockets << socket;
                          connect(socket, SIGNAL(readyRead()), this, SLOT(onBroadcastIpSocketReadyToRead()));
                      } else {
                          delete socket;
                      }
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      qDeleteAll(m_sendSockets);
                      qDeleteAll(m_recvSockets);
                      delete ui;
                  }
                  
                  void MainWindow::onPushButtonBroadcastClicked()
                  {
                      QString msg = ui->lineEdit->text();
                  
                      for (int i = 0; i < m_sendSockets.count(); i++) {
                          QUdpSocket* socket = m_sendSockets.value(i);
                          if (socket == NULL) {
                              continue;
                          }
                  
                          socket->writeDatagram(msg.toUtf8(), QHostAddress::Broadcast, recvPort);
                      }
                  }
                  
                  void MainWindow::onLocalIpSocketReadyToRead()
                  {
                      QUdpSocket* socket = qobject_cast<QUdpSocket*>(QObject::sender());
                      if (socket == NULL) {
                          return;
                      }
                  
                      while (socket->hasPendingDatagrams()) {
                          QHostAddress hostAddress;
                          quint16 hostPort;
                          QByteArray data;
                          data.resize(socket->pendingDatagramSize());
                          socket->readDatagram(data.data(), data.size(), &hostAddress, &hostPort);
                          QString msg = QString("%1:%2 - %3").arg(hostAddress.toString()).arg(hostPort).arg(QString::fromUtf8(data.constData(), data.size()));
                  
                          ui->textEditLocalIp->append(msg);
                      }
                  }
                  
                  void MainWindow::onBroadcastIpSocketReadyToRead()
                  {
                      QUdpSocket* socket = qobject_cast<QUdpSocket*>(QObject::sender());
                      if (socket == NULL) {
                          return;
                      }
                  
                      while (socket->hasPendingDatagrams()) {
                          QHostAddress hostAddress;
                          quint16 hostPort;
                          QByteArray data;
                          data.resize(socket->pendingDatagramSize());
                          socket->readDatagram(data.data(), data.size(), &hostAddress, &hostPort);
                          QString msg = QString("%1:%2 - %3").arg(hostAddress.toString()).arg(hostPort).arg(QString::fromUtf8(data.constData(), data.size()));
                  
                          ui->textEditBroadcastIp->append(msg);
                      }
                  }
                  

                  cap.jpg

                  cap2.png

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    mrdebug
                    wrote on 13 Dec 2021, 14:47 last edited by mrdebug
                    #9

                    After a while I have found the solution. There is a different behaviour or QUdpSocket->bind() function between Linux / Mac and Windows, related to AnyIPv4 attribute.
                    In order to discover each onvif devices in the network the right approach is:

                        for (int count= 0; count< QNetworkInterface::allAddresses().count(); count++) {
                            if (QNetworkInterface::allAddresses().at(count).protocol()== QAbstractSocket::IPv4Protocol && QNetworkInterface::allAddresses().at(count)!= QHostAddress(QHostAddress::LocalHost)) {
                                QUdpSocket *pQUdpSocket= new QUdpSocket(this);
                                pQUdpSocket->bind(QNetworkInterface::allAddresses().at(count), 3702, QAbstractSocket::DontShareAddress | QAbstractSocket::ReuseAddressHint);
                                pQUdpSocket->joinMulticastGroup(QHostAddress("239.255.255.250"));
                                connect(pQUdpSocket, SIGNAL(readyRead()), this, SLOT(DiscoveringPendingDatagrams()));
                                QVQUdpSockets.append(pQUdpSocket);
                            }
                        }
                    

                    These lines of code work and ere been tested on Windows, Linux and Mac.

                    Need programmers to hire?
                    www.labcsp.com
                    www.denisgottardello.it
                    GMT+1
                    Skype: mrdebug

                    K 1 Reply Last reply 13 Dec 2021, 15:02
                    1
                    • M mrdebug
                      13 Dec 2021, 14:47

                      After a while I have found the solution. There is a different behaviour or QUdpSocket->bind() function between Linux / Mac and Windows, related to AnyIPv4 attribute.
                      In order to discover each onvif devices in the network the right approach is:

                          for (int count= 0; count< QNetworkInterface::allAddresses().count(); count++) {
                              if (QNetworkInterface::allAddresses().at(count).protocol()== QAbstractSocket::IPv4Protocol && QNetworkInterface::allAddresses().at(count)!= QHostAddress(QHostAddress::LocalHost)) {
                                  QUdpSocket *pQUdpSocket= new QUdpSocket(this);
                                  pQUdpSocket->bind(QNetworkInterface::allAddresses().at(count), 3702, QAbstractSocket::DontShareAddress | QAbstractSocket::ReuseAddressHint);
                                  pQUdpSocket->joinMulticastGroup(QHostAddress("239.255.255.250"));
                                  connect(pQUdpSocket, SIGNAL(readyRead()), this, SLOT(DiscoveringPendingDatagrams()));
                                  QVQUdpSockets.append(pQUdpSocket);
                              }
                          }
                      

                      These lines of code work and ere been tested on Windows, Linux and Mac.

                      K Offline
                      K Offline
                      KroMignon
                      wrote on 13 Dec 2021, 15:02 last edited by KroMignon
                      #10

                      @mrdebug said in QUdpSocket and broadcast receiver:

                      for (int count= 0; count< QNetworkInterface::allAddresses().count(); count++) {
                          if (QNetworkInterface::allAddresses().at(count).protocol()== QAbstractSocket::IPv4Protocol && QNetworkInterface::allAddresses().at(count)!= QHostAddress(QHostAddress::LocalHost)) {
                              QUdpSocket *pQUdpSocket= new QUdpSocket(this);
                              pQUdpSocket->bind(QNetworkInterface::allAddresses().at(count), 3702, QAbstractSocket::DontShareAddress | QAbstractSocket::ReuseAddressHint);
                              pQUdpSocket->joinMulticastGroup(QHostAddress("239.255.255.250"));
                              connect(pQUdpSocket, SIGNAL(readyRead()), this, SLOT(DiscoveringPendingDatagrams()));
                              QVQUdpSockets.append(pQUdpSocket);
                          }
                      }
                      

                      This code don't looks very good to me :(
                      Please avoid multiple calling of QNetworkInterface::allAddresses(). This don't make sense, you always work with a new list instance!
                      I would prefer something like:

                      for(const auto & interface : QNetworkInterface::allAddresses())
                      {
                          if (interface.protocol() == QAbstractSocket::IPv4Protocol && interface != QHostAddress(QHostAddress::LocalHost)) {
                              auto pQUdpSocket = new QUdpSocket(this);
                              pQUdpSocket->bind(interface, 3702, QAbstractSocket::DontShareAddress | QAbstractSocket::ReuseAddressHint);
                              pQUdpSocket->joinMulticastGroup(QHostAddress("239.255.255.250"));
                              connect(pQUdpSocket, SIGNAL(readyRead()), this, SLOT(DiscoveringPendingDatagrams()));
                              QVQUdpSockets.append(pQUdpSocket);
                          }
                      }
                      

                      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

                      • Login

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