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. A UDP socket send/receive.
Forum Updated to NodeBB v4.3 + New Features

A UDP socket send/receive.

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 4 Posters 6.9k 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.
  • J Offline
    J Offline
    jenya7
    wrote on last edited by
    #1

    I have a class

    MyUDP::MyUDP(QObject *parent) : QObject(parent)
    {
        // create a QUDP socket
        socket = new QUdpSocket(this);
    }
    
    void MyUDP::Start(QString local_ip, quint16 local_port)
    {
        socket->bind(QHostAddress(local_ip), local_port);
        connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()));
    }
    
    void MyUDP::Send(QString data, QString remote_ip, quint16 remote_port)
    {
        QByteArray Data;
        Data.append(data);
    
        socket->writeDatagram(Data, QHostAddress(remote_ip), remote_port);
    }
    
    void MyUDP::ReadyRead()
    {
        // when data comes in
        QByteArray buffer;
        buffer.resize(socket->pendingDatagramSize());
    
        QHostAddress sender;
        quint16 senderPort;
    
        socket->readDatagram(buffer.data(), buffer.size(),
                             &sender, &senderPort);
    
        qDebug() << "Message from: " << sender.toString();
        qDebug() << "Message port: " << senderPort;
        qDebug() << "Message: " << buffer;
    }
    

    And I have two buttons CONNECT and SEND in mainwindow.cpp

    static MyUDP udp;
    
    void MainWindow::on_ButtonStartConnection_clicked()
    {
        QString loc_ip = ui->lineEditLocalIP->text();
        quint16 loc_port =static_cast<quint16>(ui->spinBoxLocalPort->value());
    
        udp.Start(loc_ip, loc_port);
    }
    
    void MainWindow::on_ButtonSendNetMessage_clicked()
    {
        QString rem_ip = ui->lineEditRemoteIP->text();
        quint16 rem_port = static_cast<quint16>(ui->spinBoxRemotePort->value());
    
        QString message = ui->textEditNetTX->toPlainText();
    
        udp.Send(message, rem_ip, rem_port);
    }
    

    Connect - OK.
    Send - OK - remote units get messages.
    However I never receive from the remote units, also I connected the event - connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()));

    What do I miss?

    JonBJ 1 Reply Last reply
    0
    • J jenya7

      I have a class

      MyUDP::MyUDP(QObject *parent) : QObject(parent)
      {
          // create a QUDP socket
          socket = new QUdpSocket(this);
      }
      
      void MyUDP::Start(QString local_ip, quint16 local_port)
      {
          socket->bind(QHostAddress(local_ip), local_port);
          connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()));
      }
      
      void MyUDP::Send(QString data, QString remote_ip, quint16 remote_port)
      {
          QByteArray Data;
          Data.append(data);
      
          socket->writeDatagram(Data, QHostAddress(remote_ip), remote_port);
      }
      
      void MyUDP::ReadyRead()
      {
          // when data comes in
          QByteArray buffer;
          buffer.resize(socket->pendingDatagramSize());
      
          QHostAddress sender;
          quint16 senderPort;
      
          socket->readDatagram(buffer.data(), buffer.size(),
                               &sender, &senderPort);
      
          qDebug() << "Message from: " << sender.toString();
          qDebug() << "Message port: " << senderPort;
          qDebug() << "Message: " << buffer;
      }
      

      And I have two buttons CONNECT and SEND in mainwindow.cpp

      static MyUDP udp;
      
      void MainWindow::on_ButtonStartConnection_clicked()
      {
          QString loc_ip = ui->lineEditLocalIP->text();
          quint16 loc_port =static_cast<quint16>(ui->spinBoxLocalPort->value());
      
          udp.Start(loc_ip, loc_port);
      }
      
      void MainWindow::on_ButtonSendNetMessage_clicked()
      {
          QString rem_ip = ui->lineEditRemoteIP->text();
          quint16 rem_port = static_cast<quint16>(ui->spinBoxRemotePort->value());
      
          QString message = ui->textEditNetTX->toPlainText();
      
          udp.Send(message, rem_ip, rem_port);
      }
      

      Connect - OK.
      Send - OK - remote units get messages.
      However I never receive from the remote units, also I connected the event - connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()));

      What do I miss?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @jenya7 said in A UDP socket send/receive.:

      connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()))

      I see a slot ReadyRead, but what is this SIGNAL(ReadyRead())? If you changed over to New Signal Slot Syntax it would not compile if you have not defined the signal. If you must stick with old style connects, at least check the return result of your connect()s, and be prepared for runtime errors....

      Separately, static MyUDP udp;, what do you need/want a static variable for, probably not a good idea at all.

      1 Reply Last reply
      4
      • J Offline
        J Offline
        jenya7
        wrote on last edited by
        #3

        So, a signal is my void MyUDP::ReadyRead()? And what is a slot? I should implement it? In what file?
        static - to limit the scope to the current file. may be I need it outside I don't know.

        jsulmJ J.HilkJ 2 Replies Last reply
        0
        • J jenya7

          So, a signal is my void MyUDP::ReadyRead()? And what is a slot? I should implement it? In what file?
          static - to limit the scope to the current file. may be I need it outside I don't know.

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

          @jenya7 Please read documentation: there is no signal ReadyRead in QUdpSocket, but https://doc.qt.io/qt-5/qiodevice.html#readyRead
          And static variables should be avoided as much as possible. Usually they are a sign for bad design.

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

          J 1 Reply Last reply
          2
          • jsulmJ jsulm

            @jenya7 Please read documentation: there is no signal ReadyRead in QUdpSocket, but https://doc.qt.io/qt-5/qiodevice.html#readyRead
            And static variables should be avoided as much as possible. Usually they are a sign for bad design.

            J Offline
            J Offline
            jenya7
            wrote on last edited by jenya7
            #5

            @jsulm said in A UDP socket send/receive.:

            @jenya7 Please read documentation: there is no signal ReadyRead in QUdpSocket, but https://doc.qt.io/qt-5/qiodevice.html#readyRead
            And static variables should be avoided as much as possible. Usually they are a sign for bad design.

            OK. So this way - connect(socket, SIGNAL(readyRead()), this, SLOT(ReadyRead())); on readyRead my ReadyRead is invoked?

            jsulmJ 1 Reply Last reply
            0
            • J jenya7

              @jsulm said in A UDP socket send/receive.:

              @jenya7 Please read documentation: there is no signal ReadyRead in QUdpSocket, but https://doc.qt.io/qt-5/qiodevice.html#readyRead
              And static variables should be avoided as much as possible. Usually they are a sign for bad design.

              OK. So this way - connect(socket, SIGNAL(readyRead()), this, SLOT(ReadyRead())); on readyRead my ReadyRead is invoked?

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

              @jenya7 Yes.
              But as @JonB already suggested you should switch to new Qt5 syntax to detect such issues already at compile time.
              See https://wiki.qt.io/New_Signal_Slot_Syntax/de

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

              1 Reply Last reply
              1
              • J jenya7

                So, a signal is my void MyUDP::ReadyRead()? And what is a slot? I should implement it? In what file?
                static - to limit the scope to the current file. may be I need it outside I don't know.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @jenya7

                what you wrote:

                connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()));
                

                what it should be:
                Qt5 and Qt6

                connect(socket, & QUdpSocket::readyRead, this,  &MyUDP::ReadyRead);
                

                Qt4 and earlier:

                bool connectWasSuccessfull = connect(socket, SIGNAL(readyRead()), this, SLOT(ReadyRead()));
                Q_ASSERT(connectWasSuccessfull);
                

                you should read up on signal and slots and on static. Because static does not "limit anything to only 1 file"


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                J 1 Reply Last reply
                1
                • J.HilkJ J.Hilk

                  @jenya7

                  what you wrote:

                  connect(socket, SIGNAL(ReadyRead()), this, SLOT(ReadyRead()));
                  

                  what it should be:
                  Qt5 and Qt6

                  connect(socket, & QUdpSocket::readyRead, this,  &MyUDP::ReadyRead);
                  

                  Qt4 and earlier:

                  bool connectWasSuccessfull = connect(socket, SIGNAL(readyRead()), this, SLOT(ReadyRead()));
                  Q_ASSERT(connectWasSuccessfull);
                  

                  you should read up on signal and slots and on static. Because static does not "limit anything to only 1 file"

                  J Offline
                  J Offline
                  jenya7
                  wrote on last edited by jenya7
                  #8

                  @J-Hilk
                  I have Qt 4.8. Indeed this SIGNAL(readyRead() is quite unclear. This way QUdpSocket::readyRead it's clear and I can see all events on smart autocomplete.
                  One more thing - how can I display a received message to a user? Say in textEdit. qDebug() is not usefull in a real application. How can I pass the data outside the class? Outside the void MyUDP::ReadyRead().

                  On signal event I get to MyUDP::ReadyRead() but who is signaling to UI to display message?

                  jsulmJ 1 Reply Last reply
                  0
                  • J jenya7

                    @J-Hilk
                    I have Qt 4.8. Indeed this SIGNAL(readyRead() is quite unclear. This way QUdpSocket::readyRead it's clear and I can see all events on smart autocomplete.
                    One more thing - how can I display a received message to a user? Say in textEdit. qDebug() is not usefull in a real application. How can I pass the data outside the class? Outside the void MyUDP::ReadyRead().

                    On signal event I get to MyUDP::ReadyRead() but who is signaling to UI to display message?

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

                    @jenya7 said in A UDP socket send/receive.:

                    How can I pass the data outside the class?

                    Using signals and slots. In your MyUDP class add a signal with a QString parameter. Then emit this signal when you want to show a message with the text as signal parameter. Connect this signal with a slot in your GUI class which is responsible for showing the message. In this slot you can show the text then.

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

                    J 1 Reply Last reply
                    3
                    • jsulmJ jsulm

                      @jenya7 said in A UDP socket send/receive.:

                      How can I pass the data outside the class?

                      Using signals and slots. In your MyUDP class add a signal with a QString parameter. Then emit this signal when you want to show a message with the text as signal parameter. Connect this signal with a slot in your GUI class which is responsible for showing the message. In this slot you can show the text then.

                      J Offline
                      J Offline
                      jenya7
                      wrote on last edited by jenya7
                      #10

                      @jsulm said in A UDP socket send/receive.:

                      @jenya7 said in A UDP socket send/receive.:

                      How can I pass the data outside the class?

                      Using signals and slots. In your MyUDP class add a signal with a QString parameter. Then emit this signal when you want to show a message with the text as signal parameter. Connect this signal with a slot in your GUI class which is responsible for showing the message. In this slot you can show the text then.

                      Sorry I fail to understand. Right now the receiving is working and I got the message in a global string
                      msg = QString(udp_buffer);
                      Now what signal do I emit?

                      jsulmJ 1 Reply Last reply
                      0
                      • J jenya7

                        @jsulm said in A UDP socket send/receive.:

                        @jenya7 said in A UDP socket send/receive.:

                        How can I pass the data outside the class?

                        Using signals and slots. In your MyUDP class add a signal with a QString parameter. Then emit this signal when you want to show a message with the text as signal parameter. Connect this signal with a slot in your GUI class which is responsible for showing the message. In this slot you can show the text then.

                        Sorry I fail to understand. Right now the receiving is working and I got the message in a global string
                        msg = QString(udp_buffer);
                        Now what signal do I emit?

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

                        @jenya7 said in A UDP socket send/receive.:

                        Now what signal do I emit?

                        One you need to define in your MyUDP class as I wrote before:

                        class MyUDP...
                        {
                        signals:
                            void showMessage(const QString& msg);
                        ...
                        void MyUDP::ReadyRead()
                        {
                           ...
                           showMessage(QString(buffer));
                        

                        Please read https://doc.qt.io/qt-5/signalsandslots.html

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

                        J 1 Reply Last reply
                        2
                        • jsulmJ jsulm

                          @jenya7 said in A UDP socket send/receive.:

                          Now what signal do I emit?

                          One you need to define in your MyUDP class as I wrote before:

                          class MyUDP...
                          {
                          signals:
                              void showMessage(const QString& msg);
                          ...
                          void MyUDP::ReadyRead()
                          {
                             ...
                             showMessage(QString(buffer));
                          

                          Please read https://doc.qt.io/qt-5/signalsandslots.html

                          J Offline
                          J Offline
                          jenya7
                          wrote on last edited by
                          #12

                          @jsulm
                          Wow. That's cool. And I can implement showMessage(const QString& msg); in any file?
                          Say ui->textEditNetRX->append(msg); is available in "mainwindow.cpp.

                          jsulmJ 1 Reply Last reply
                          0
                          • J jenya7

                            @jsulm
                            Wow. That's cool. And I can implement showMessage(const QString& msg); in any file?
                            Say ui->textEditNetRX->append(msg); is available in "mainwindow.cpp.

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

                            @jenya7 said in A UDP socket send/receive.:

                            in any file?

                            Yes, just add a slot where you need it and connect it to the signal.
                            Signals/slots is a very powerful concept and it also helps to decouple classes from each other. For example your MyUDP class does not need to know who connects to its signal, it just emits the signal. You can connect 0..n slots to a signal, you can connect a signal to 0..n other signals.

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

                            J 1 Reply Last reply
                            2
                            • jsulmJ jsulm

                              @jenya7 said in A UDP socket send/receive.:

                              in any file?

                              Yes, just add a slot where you need it and connect it to the signal.
                              Signals/slots is a very powerful concept and it also helps to decouple classes from each other. For example your MyUDP class does not need to know who connects to its signal, it just emits the signal. You can connect 0..n slots to a signal, you can connect a signal to 0..n other signals.

                              J Offline
                              J Offline
                              jenya7
                              wrote on last edited by
                              #14

                              @jsulm
                              Thank you very much.

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                jenya7
                                wrote on last edited by
                                #15

                                In mainwindow.h I created a slot

                                class MainWindow : public QMainWindow
                                {
                                    Q_OBJECT
                                
                                public:
                                    explicit MainWindow(QWidget *parent = nullptr);
                                    ~MainWindow();
                                
                                    MyUDP udp;
                                
                                public slots:
                                    void ShowUdpMessage(const QString& msg, const QByteArray data);
                                //and so on...
                                

                                in mainwindow.cpp

                                void MainWindow::ShowUdpMessage(const QString& msg, const QByteArray data)
                                {
                                    QByteArray arr = data;
                                    ui->textEditNetRX->append(msg);
                                }
                                

                                now in main.cpp

                                
                                MainWindow w;
                                 w.show();
                                
                                QObject::connect(&???, &???, &w, &MainWindow::ShowUdpMessage);
                                

                                How do I tie the signal source?
                                The signal generates by MyUDP udp that resides in the MainWindow class.

                                jsulmJ 1 Reply Last reply
                                0
                                • J jenya7

                                  In mainwindow.h I created a slot

                                  class MainWindow : public QMainWindow
                                  {
                                      Q_OBJECT
                                  
                                  public:
                                      explicit MainWindow(QWidget *parent = nullptr);
                                      ~MainWindow();
                                  
                                      MyUDP udp;
                                  
                                  public slots:
                                      void ShowUdpMessage(const QString& msg, const QByteArray data);
                                  //and so on...
                                  

                                  in mainwindow.cpp

                                  void MainWindow::ShowUdpMessage(const QString& msg, const QByteArray data)
                                  {
                                      QByteArray arr = data;
                                      ui->textEditNetRX->append(msg);
                                  }
                                  

                                  now in main.cpp

                                  
                                  MainWindow w;
                                   w.show();
                                  
                                  QObject::connect(&???, &???, &w, &MainWindow::ShowUdpMessage);
                                  

                                  How do I tie the signal source?
                                  The signal generates by MyUDP udp that resides in the MainWindow class.

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

                                  @jenya7

                                  QObject::connect(&udp, &MyUDP::showMessage, &w, &MainWindow::ShowUdpMessage);
                                  

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

                                  J 1 Reply Last reply
                                  1
                                  • jsulmJ jsulm

                                    @jenya7

                                    QObject::connect(&udp, &MyUDP::showMessage, &w, &MainWindow::ShowUdpMessage);
                                    
                                    J Offline
                                    J Offline
                                    jenya7
                                    wrote on last edited by
                                    #17

                                    @jsulm
                                    QObject::connect(&udp, &MyUDP::showMessage, &w, &MainWindow::ShowUdpMessage);
                                    &udp - is not visible in the scope. also MainWindow::udp <- udp not recognized although it declared public:MyUDP udp; in MainWindow.

                                    jsulmJ 1 Reply Last reply
                                    0
                                    • J jenya7

                                      @jsulm
                                      QObject::connect(&udp, &MyUDP::showMessage, &w, &MainWindow::ShowUdpMessage);
                                      &udp - is not visible in the scope. also MainWindow::udp <- udp not recognized although it declared public:MyUDP udp; in MainWindow.

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

                                      @jenya7 You should do the connection inside MainWindow (for example in its constructor), because MainWindow needs the signal and it also has the MyUDP instance...

                                      "although it declared public:MyUDP udp" - don't declare it public, just do the connection inside MainWindow.

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

                                      1 Reply Last reply
                                      1
                                      • J Offline
                                        J Offline
                                        jenya7
                                        wrote on last edited by jenya7
                                        #19

                                        I try in the constructor

                                        MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
                                        {
                                            ui->setupUi(this);
                                            ui->tabWidget->setCurrentIndex(0);
                                            ui->textEditTerminalTx->installEventFilter(this);
                                            
                                             QObject::connect(&udp, &MyUDP::ShowUdpMessage, &MainWindow, &MainWindow::ShowUdpMessage);
                                        }
                                        

                                        third argument - &MainWindow <- 'MainWindow' does not refer to a value.

                                        JonBJ 1 Reply Last reply
                                        0
                                        • J jenya7

                                          I try in the constructor

                                          MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
                                          {
                                              ui->setupUi(this);
                                              ui->tabWidget->setCurrentIndex(0);
                                              ui->textEditTerminalTx->installEventFilter(this);
                                              
                                               QObject::connect(&udp, &MyUDP::ShowUdpMessage, &MainWindow, &MainWindow::ShowUdpMessage);
                                          }
                                          

                                          third argument - &MainWindow <- 'MainWindow' does not refer to a value.

                                          JonBJ Offline
                                          JonBJ Offline
                                          JonB
                                          wrote on last edited by JonB
                                          #20

                                          @jenya7
                                          &MainWindow should be this. And you ought understand why (it's an instance of MainWindow).

                                          1 Reply Last reply
                                          3

                                          • Login

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