Могу ли я использовать опросы QUdpSockets wo или пользовательские классы в Qt? - PullRequest
0 голосов
/ 16 января 2019

Ниже приведен короткий пример UDP-сервера в Qt, который работает, но мне не нравится, что я опрашиваю, чтобы узнать, доступны ли новые данные. Я сталкивался с некоторыми примерами readyRead (), но все они, кажется, представляют класс qt. Нужно ли использовать класс qt, чтобы воспользоваться сигналом readyRead ()?

Вот рабочий, но простой UDP-сервер, полностью реализованный на основном:

#include <QDebug>
#include <QUdpSocket>
#include <QThread>

int main(int argc, char *argv[])
{
    QUdpSocket *socket = new QUdpSocket();
    u_int16_t port = 7777;

    bool bindSuccess =  socket->bind(QHostAddress::AnyIPv4, port);
    if (!bindSuccess) {
        qDebug() << "Error binding to port " << port << " on local IPs";
        return a.exec();
    }
    qDebug() << "Started UDP Server on " << port << endl;

    QHostAddress sender;
    while (true) {
        while (socket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(socket->pendingDatagramSize());
            socket->readDatagram(datagram.data(),datagram.size(),&sender,&port);
            qDebug() << "Message From :: " << sender.toString();
            qDebug() << "Port From :: "<< port;
            qDebug() << "Message :: " << datagram.data();
        }
        QThread::msleep(20);
    }

    return 0;
}

Вот пример сигнала readyRead (): https://www.bogotobogo.com/Qt/Qt5_QUdpSocket.php

Я пока не понял, как заставить это работать. Я должен делать что-то не так. Вот код соединения UDP, который я пытаюсь:

#include "myudp.h"

MyUDP::MyUDP(QObject *parent) : QObject(parent) {
}

void MyUDP::initSocket(u_int16_t p) {
    port = p;

    udpSocket = new QUdpSocket(this);
    bool bindSuccess = udpSocket->bind(QHostAddress::LocalHost, port);
    if (!bindSuccess) {
        qDebug() << "Error binding to port " << port << " on local IPs";
        return;
    }
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}

void MyUDP::readPendingDatagrams() {
    QHostAddress sender;
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &port);
        qDebug() << "Message From :: " << sender.toString();
        qDebug() << "Port From :: " << port;
        qDebug() << "Message :: " << datagram.data();
    }
}

myudp.h

#include <QObject>
#include <QUdpSocket>

class MyUDP : public QObject
{
    Q_OBJECT
public:
    explicit MyUDP(QObject *parent);
    void initSocket(u_int16_t p);

    u_int16_t port;
    QUdpSocket *udpSocket;

signals:

public slots:
    void readPendingDatagrams();
};

новый main.cpp

int main(int argc, char *argv[]) 
{
    MyUDP *myUDP = new MyUDP(0);
    myUDP->initSocket(port);

    while (true) {
        usleep(1000);
    }

    return 0;
}

Я тестирую с:

netcat 127.0.0.1 -u 7777
{"cid"="0x1234123412341", "fill_level"=3245 }<cr>

1 Ответ

0 голосов
/ 16 января 2019

Что вы делаете неправильно, так это то, что вы не запускаете цикл обработки событий Qt. то есть это неверно:

int main(int argc, char *argv[]) 
{
   MyUDP *myUDP = new MyUDP(0);
   myUDP->initSocket(port);

   while (true) {
       usleep(1000);
   }

   return 0;
}

... вместо этого у вас должно быть что-то вроде этого:

int main(int argc, char *argv[]) 
{
   QApplication app(argc, argv);

   // connect needs to occur after QCoreApplication declaration
   MyUDP *myUDP = new MyUDP(0);
   myUDP->initSocket(port);

   return app.exec();
}

... он находится внутри вызова app.exec(), где приложение Qt проводит большую часть своего времени (app.exec() не вернется, пока Qt не захочет выйти), и именно там Qt будет обрабатывать I / сокет вашего UDP-сокета O и необходимость сигнализации.

...