当前位置: 代码迷 >> QT开发 >> ! udp多线程的有关问题
  详细解决方案

! udp多线程的有关问题

热度:248   发布时间:2016-04-25 03:01:29.0
求助! udp多线程的问题
我做了个udp接收的测试程序,刚开始能收到数据,收了几条数据之后就报个错:
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
然后程序就收不到数据了,但是程序没有崩溃。用的是qt5.4
各位能帮我看下吗,感激不尽!

代码如下:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "udpthread.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void showmessages(QString messages);

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    UdpThread *myUdpThread;
};

#endif // MAINWINDOW_H


udpthread.h
#ifndef UDPTHREAD_H
#define UDPTHREAD_H

#include <QThread>
#include <QUdpSocket>
#include <QtNetwork>

class UdpThread : public QThread
{
    Q_OBJECT

public:
    UdpThread(QObject *parent=0);
    ~UdpThread();
    void run()Q_DECL_OVERRIDE;
signals:
    void showmessages(QString messages);

private slots:
    void readPendingDatagrams();

private:
    QUdpSocket *myUdpSocket;
};

#endif // UDPTHREAD_H


mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showmessages(QString messages)    //显示数据
{
    ui->textEdit->append(messages);
}

void MainWindow::on_pushButton_clicked()     //开启udp
{
    myUdpThread=new UdpThread(this);
    connect(myUdpThread, SIGNAL(showmessages(QString)),
                this, SLOT(showmessages(QString)));
    myUdpThread->start();
}



udpthread.cpp
#include "udpthread.h"
#include <QUdpSocket>



UdpThread::UdpThread(QObject *parent)
    :QThread(parent)
{
}

UdpThread::~UdpThread()
{
    this->myUdpSocket->deleteLater();
    quit();
    wait();
}

void UdpThread::run()
{
    qDebug()<<"run";
    myUdpSocket=new QUdpSocket();
    if(myUdpSocket->bind(60004, QUdpSocket::ShareAddress |  //绑定
                         QUdpSocket::ReuseAddressHint )){
        qDebug()<<"bind_success";
    }
    else {
        qDebug()<<"bind_fail";
        return;
    }
    connect(myUdpSocket, SIGNAL(readyRead()),
                this, SLOT(readPendingDatagrams()));
    exec();
}

void UdpThread::readPendingDatagrams()
{
    while(myUdpSocket->hasPendingDatagrams()){
        QByteArray datagram;
        datagram.resize(myUdpSocket->pendingDatagramSize());
        qDebug()<<"readPendingDatagrams-1";
        myUdpSocket->readDatagram(datagram.data(), datagram.size()); //接收数据(根据qDebug信息,就是执行这条语句报错!!!)
        qDebug()<<"readPendingDatagrams-2";
        emit showmessages(datagram); //显示数据
    }
}



下面是调试信息:
run
bind_success
readPendingDatagrams-1
readPendingDatagrams-2
readPendingDatagrams-1
readPendingDatagrams-2
readPendingDatagrams-1
readPendingDatagrams-2
readPendingDatagrams-1
readPendingDatagrams-2
readPendingDatagrams-1
readPendingDatagrams-2
readPendingDatagrams-1
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
readPendingDatagrams-2

------解决思路----------------------
你的signal是另外一个线程发出的  而你的UI是主线程  主线程里不要绑定非UI线程的signal  而应该受到这个signal后 再次抛出一个signal去调用主线程的slot
------解决思路----------------------
目测这样写应该可以解决问题.

    connect(myUdpSocket, SIGNAL(readyRead()),
                this, SLOT(readPendingDatagrams()), Qt::DirectConnection);
  相关解决方案