c++ - QThread 中未收到 udp 数据包

标签 c++ multithreading qt sockets qthread

我正在尝试使用我在单独的 QThread 中使用 qUdpSocket 编写的 udpReceiver 类接收一些数据包:

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 的原因。 如果您能帮我解决这个问题,我将不胜感激 :) 问候,

最佳答案

在 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 并在您的 QObject 上调用 moveToThread 以移动它到新线程)。您将从输出中看到创建 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 代码,所以我不知道那里有什么问题。如果您遇到困难,请随时发布另一个问题并在评论中提及,我会尽力提供帮助。

关于c++ - QThread 中未收到 udp 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19375141/

相关文章:

c++ - 全局静态变量实例化行为

c++ - 返回 const int* 与返回 const int* 引用

c# - 在我的计划循环中重新分配 DateTime 对象的值时,DateTime 多线程 UDP 发送方具有非常不同的时间结果

c++ - QSpinBox 千位分隔符

c++ - 如何完全访问 OpenCV 垫中的一维?

c++ - 关于rint使用的问题

java - Java中的静态和非静态同步

java - Groovy ASTBuilder 多线程性能不佳

qt - 无法加载 Qt 插件

regex - QML 中时间输入的文本字段验证