0

我正在尝试使用udpReceiverqUdpSocket单独编写的类来接收一些数据包QThread

class udpThread : public QThread
{
private:
    QObject * parent;
public:
    udpThread(QObject * parent = 0)
    {
        this->parent = parent;
    }

    void run()
    {
        UdpReceiver * test = new UdpReceiver(parent);
    }
};


class UdpReceiver : public QObject
{
    Q_OBJECT
private:
    QUdpSocket * S;
    int port;
public:
    UdpReceiver(QObject* parent = 0) : QObject(parent)
    {
        port = 9003;
        initialize();
    }
    UdpReceiver(int p,QObject* parent = 0) : QObject(parent)
    {
        port = p;
        initialize();
    }

    void initialize()
    {
        S = new QUdpSocket();
        S->bind(port);
        S->connect(S,SIGNAL(readyRead()),this,SLOT(readPendingDiagrams()));
        qDebug() << "Waiting for UDP data from port " << port << " ... \n";
    }

public slots:
    void readPendingDiagrams()
    {
        while(S->waitForReadyRead())
        {
            QByteArray datagram;
            datagram.resize(S->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;

            S->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
            qDebug() << datagram.size() << " bytes received .... \n";
            qDebug() << " bytes received .... \n";
        }
    }
};

这是main()方法:

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



//    UdpReceiver * net = new UdpReceiver();      

    MainWindow w;

    udpThread * ut = new udpThread();
    ut->start();

    w.show();


    return a.exec();
}

现在,当我使用udpReceiver该类来获取没有它的数据包时,QThread它工作得很好,但是当我使用udpThread该类时,它没有得到数据包,或者至少raedyread()信号没有以某种方式激活。当我尝试在没有QThread我的 GUI 以某种方式崩溃并且整个程序挂起的情况下获取数据包时,这就是我想使用QThread. 如果您能帮我解决这个问题,我将不胜感激:) 问候,

4

2 回答 2

1

在 Qt 中使用线程时,您已经陷入了与许多人一样的陷阱:http: //blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/。将 QThread 子类化几乎总是一个坏主意(
例请参见http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html)。

如下更改您的代码,以“预期”的方式执行它(创建一个新的QThread并调用moveToThreadQObject将其移动到新线程)。您将从输出中看到UdpReceiver创建的线程与接收数据的线程不同,这正是您想要的:

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

class UdpReceiver : public QObject
{
    Q_OBJECT
private:
    QUdpSocket * S;
    int port;
public:
    UdpReceiver(QObject* parent = 0) : QObject(parent)
    {
        qDebug() << "Construction thread:" << QThread::currentThreadId();

        port = 9003;
        initialize();
    }
    UdpReceiver(int p,QObject* parent = 0) : QObject(parent)
    {
        port = p;
        initialize();
    }

    void initialize()
    {
        S = new QUdpSocket();
        S->bind(port);
        S->connect(S,SIGNAL(readyRead()),this,SLOT(readPendingDiagrams()));
        qDebug() << "Waiting for UDP data from port " << port << " ... \n";
    }

public slots:
    void readPendingDiagrams()
    {
        qDebug() << "Reading thread:" << QThread::currentThreadId();

        while(S->waitForReadyRead())
        {
            QByteArray datagram;
            datagram.resize(S->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;

            S->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
            qDebug() << datagram.size() << " bytes received .... \n";
            qDebug() << " bytes received .... \n";
        }
    }
};

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

    QThread *t = new QThread();
    t->start();

    UdpReceiver * net = new UdpReceiver();
    net->moveToThread(t);

    return a.exec();
}

#include "main.moc"

我没有你的UI代码,所以我不知道那里有任何问题。如果您遇到问题,请随时发布另一个问题并在评论中提及,我会尽力提供帮助。

于 2013-10-15T07:26:12.240 回答
0

Vahid Nateghi,初始化代码和工作代码必须在同一个线程中运行。但是 UdpReceiver 的构造函数在主线程中运行,而 readPendingDiagrams 在主线程中运行,这就是错误。试试这个:

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

class UdpReceiver : public QObject
{
    Q_OBJECT
private:
    QUdpSocket * S;
    int port;
public:
    UdpReceiver(QObject* parent = 0) : QObject(parent)
    {
        qDebug() << ">HERE was the bug! thread:" << QThread::currentThreadId() << "in Construction of UdpReceiver:" << __LINE__ ;
    }

public slots:
    void init_thread(){
        port = 10000;
        qDebug() << ">thread:" << QThread::currentThreadId() << "in init_thread:" << __LINE__ ;
        S = new QUdpSocket();
        S->bind(port);
        S->connect(S,SIGNAL(readyRead()),this,SLOT(readPendingDiagrams()));
        qDebug() << "Waiting for UDP data from port " << port << " ... \n";
    }
    void readPendingDiagrams()
    {
        qDebug() << ">thread:" << QThread::currentThreadId() << "in readPendingDiagrams:" << __LINE__ ;


        while(S->waitForReadyRead())
        {
            QByteArray datagram;
            datagram.resize(S->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;

            S->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
            qDebug() << datagram.size() << " bytes received in thread " << QThread::currentThreadId() << "in readPendingDiagrams:" << __LINE__ ;
        }
    }
};

int main(int argc, char *argv[])
{
    qDebug() << ">Main thread:" << QThread::currentThreadId() << "in main:" << __LINE__ ;
    QCoreApplication a(argc, argv);

    QThread *t = new QThread();


    UdpReceiver * net = new UdpReceiver();
    net->moveToThread(t);
    net->connect(t,SIGNAL(started()),net,SLOT(init_thread()));
    t->start();

    return a.exec();
}

#include "main.moc"
于 2016-07-21T14:38:47.860 回答