Я пытаюсь получить некоторые пакеты, используя класс udpReceiver
который я написал с помощью qUdpSocket
в отдельном 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
мой графический интерфейс как-то падает, и вся программа зависает, поэтому я хочу использовать QThread
. Я ценю, если вы могли бы помочь мне решить эту проблему :) С уважением,
Вы попали в ту же ловушку, что и многие, когда работаете с потоками в Qt: http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/. Это почти всегда плохая идея для подкласса QThread (см. Http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html для контрпримеров).
Измените свой код следующим образом, чтобы сделать это "предполагаемым" способом (создайте новый QThread и вызовите moveToThread в свой QObject, чтобы переместить его в новый поток). Вы увидите на выходе, что поток, созданный 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"
У меня нет кода пользовательского интерфейса, поэтому я не знаю о каких-либо проблемах. Не стесняйтесь публиковать еще один вопрос, если вы застряли там и упомянете об этом в комментарии, и я постараюсь помочь.
Вахид Натеги, коды инициализации и рабочие коды должны работать в одном потоке. Но конструктор 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"