0

I'm just getting started with implementing a UDP client for my Qt application. I followed this example. I am able to send data to and receive data from a remote host. This has been verified at my remote host as well as the local client that I am developing this application for (verified locally by calling handleReadyRead() from my main.cpp). I can't seem to get the QUdpSocket to emit its readyRead signal. Why is that?

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTimer>
#include "udpclient.h"


static double value = 0;
static bool flash = true;
static UDPClient client;



   
int update1000()
{
    QByteArray Data;
    Data.append((char) 0x00);
    Data.append((char) 0x2c);
    Data.append((char) 0x1a);
    Data.append((char) 0x2c);
    Data.append((char) 0x92);
    Data.append((char) 0xe6);
    Data.append((char) 0xf6);
    Data.append((char) 0xa0);
    client.SendPacket(Data);

    return 0;
}

int packetReady()
{
    qInfo() << "packetReady";
    return 0;
}



int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    qmlRegisterType<HorizontalBarGraph>("com.kubie.horizontalBarGraph", 1, 0, "HorizontalBarGraph");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    


    QObject *object = engine.rootObjects()[0];
   

    

    //qInfo() << "Initializing timer.";    
    QTimer timer1000;
    QObject::connect(&timer1000, &QTimer::timeout, update1000);
    timer1000.start(1000);



    return app.exec();
}

udpclient.h

#ifndef UDPCLIENT_H
#define UDPCLIENT_H


#include <QUdpSocket>

class UDPClient : public QObject
{
  Q_OBJECT

  public:
      explicit UDPClient(QObject *parent = nullptr);

      void SendPacket(const QByteArray &buffer);


  private:
      QUdpSocket *socket = nullptr;

  signals:

  public slots:
      void handleReadyRead();

};

#endif // UDPCLIENT_H

udpclient.cpp

#include "udpclient.h"

UDPClient::UDPClient(QObject *parent) :
    QObject(parent)
{
  socket = new QUdpSocket(this);

  //We need to bind the UDP socket to an address and a port
  //socket->bind(QHostAddress::LocalHost,1234);         //ex. Address localhost, port 1234
  socket->bind(QHostAddress::AnyIPv4,6969);         //ex. Address localhost, port 1234

  //connect(socket,SIGNAL(readyRead()),this,SLOT(handleReadyRead()));
  connect(socket, &QUdpSocket::readyRead, this, &UDPClient::handleReadyRead);

}


void UDPClient::SendPacket(const QByteArray &buffer)
{
    socket->writeDatagram(buffer, QHostAddress("192.168.174.10"), 6969);
}


void UDPClient::handleReadyRead()     //Read something
{
    qInfo() << socket->hasPendingDatagrams();

  QByteArray Buffer;
  Buffer.resize(socket->pendingDatagramSize());

  QHostAddress sender;
  quint16 senderPort;
  socket->readDatagram(Buffer.data(),Buffer.size(),&sender,&senderPort);
  qInfo() << Buffer;

  //The address will be sender.toString()
}
kubiej21
  • 700
  • 4
  • 14
  • 29
  • Are you sure your firewall does not block it? Or the ttl is to small so the packet is discarded by your network. Try it with two local processes. – chehrlic Jan 17 '21 at 18:00
  • If I call handleReadyRead from my main, I can see the expected data. This indicates that the firewall is not blocking the packet, nor is the packet being discarded prematurely due to a small ttl. The packet has arrived at its final destination, just no signal is being emitted by the QUdpSocket class. – kubiej21 Jan 17 '21 at 18:03
  • Is UDPClient in a separate thread? Please provide a minimal, compilable example. – chehrlic Jan 17 '21 at 18:52
  • Added my main.cpp. – kubiej21 Jan 17 '21 at 19:07
  • This looks really strange... I would suggest you to rewrite it without global statics. The problem I see here is that the QUdpSocket is created *before* a Q(Gui)Application is created which will likely not work (and should print some warnings on startup). – chehrlic Jan 17 '21 at 19:10
  • Creating my UDPClient after QGuiApplication seems to have done the trick. I wasn't getting any warnings on startup - would this indicate that I'm not using the correct compiler flags? – kubiej21 Jan 17 '21 at 19:23
  • This has nothing to do with compiler flags. Are you on windows? Then you can see those output only during debugging in the application debug output window. – chehrlic Jan 17 '21 at 20:06
  • RaspberryPi. I was not using debug mode, so that is likely why I never noticed anything. Care to post your comment as an answer so I can accept it? – kubiej21 Jan 24 '21 at 17:02

1 Answers1

0

A QML application needs (at least) a QGuiApplication to run. You will get a debug output on the command line or in your IDE debug application output window about this. To get a more fatal warning for such kind of problems you can set the environment variable QT_FATAL_WARNINGS (see QDebug documentation for more information)

chehrlic
  • 913
  • 1
  • 5
  • 5