Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
I have discovered that QTcpSocket and QTcpServer has to be created in main thread in order to function properly. Created in other thread results in slots not being called. Unfortunately, my part was just writing a dll which does not know which thread is creating the class. Furthermore, running the class creation in main thread should not be a requirement. Is there a way to run them reliable in other threads? I have no ground to run network activities in a UI thread.
Many Thanks!
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
where have you read that?
In Qt4 you can either:
* work with blocking I/O (not in the gui thread, as otherwise your app freezes til the I/O is over)
* work with non-blocking I/O: you need a QEventLoop running in your thread - you may use the main (i.e. gui) thread, but you do not have to.
HTH
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
caduel
where have you read that?
In Qt4 you can either:
* work with blocking I/O (not in the gui thread, as otherwise your app freezes til the I/O is over)
* work with non-blocking I/O: you need a QEventLoop running in your thread - you may use the main (i.e. gui) thread, but you do not have to.
HTH
Do you know how to use QNetworkAccessManager with QEventLoop other than the one in the main thread?
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
caduel
where have you read that?
In Qt4 you can either:
* work with blocking I/O (not in the gui thread, as otherwise your app freezes til the I/O is over)
* work with non-blocking I/O: you need a QEventLoop running in your thread - you may use the main (i.e. gui) thread, but you do not have to.
HTH
Here is a sample code to illustrate the problem I have encountered. I made it as brief as possible. Hence, it is not going with the best practice. Please forgive me for that.
Code:
#include <QtNetwork/QTcpServer>
#include <QtCore/QThread>
#include <QtCore/QCoreApplication>
#include <iostream>
#include <assert.h>
class ServerThread
: public QThread{
Q_OBJECT
public:
, mpServer(0)
{}
void run ()
{
bool lbOk(connect(mpServer, SIGNAL(newConnection()),
this, SLOT(onNewConnection())));
assert(lbOk);
}
private:
protected slots:
void onNewConnection()
{
std::cout << "new connection!" << std::endl;
}
};
int main(int argc, char *argv[])
{
ServerThread lrThread(0);
// lrThread.start();
lrThread.run();
return a.exec();
}
It runs fine with expected outcome which print a message every time a connection is made.
However, if the line 40 is uncommented and line 41 commented, the ServerThread::onNewConnection() method is never called with connections made.
It stops working while the QTcpServer is not created on the main thread.
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
piotr.dobrogost
Do you know how to use QNetworkAccessManager with QEventLoop other than the one in the main thread?
Thanks for the pointers. I will definitely look into that.:D
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
you need to start your QThread's event loop, see QThread::exec()
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
jan
I have discovered that QTcpSocket and QTcpServer has to be created in main thread in order to function properly.
No, this is false. The socket has to have affinity with a thread with a running event loop to function properly or it needs to use the family of waitFor*() methods if not event loop is available.
Quote:
Originally Posted by
piotr.dobrogost
Do you know how to use QNetworkAccessManager with QEventLoop other than the one in the main thread?
Code:
#include <QtGui>
#include <QtNetwork>
Q_OBJECT
public:
Thread
() : QThread(){ manager
= 0;
} ~Thread() { delete manager; }
void run(){
manager = new QNetworkAccessManager;
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(processReply(QNetworkReply*)));
QTimer::singleShot(0,
this,
SLOT(process
()));
exec();
}
public slots:
void process(){
QNetworkReply
*reply
= manager
->get
(QNetworkRequest
(QUrl("http://www.qtcentre.org/")));
QTimer::singleShot(5000,
this,
SLOT(process
()));
}
void processReply(QNetworkReply *reply){
qDebug() << reply->size();
reply->deleteLater();
}
private:
QNetworkAccessManager *manager;
};
#include "main.moc"
int main(int argc, char **argv){
Thread thread;
thread.moveToThread(&thread);
thread.start();
return app.exec();
}
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Is the purpose of this code to download the same page every 5 seconds?
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Yes. You wanted an example of QNetworkAccessManager working with a thread event loop, you didn't mention it should do something useful.
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Thanks for your sample. You make my day!
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Would
Code:
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(processReply(QNetworkReply*)), Qt::QueuedConnection);
work instead of
Code:
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(processReply(QNetworkReply*)));
QTimer::singleShot(0,
this,
SLOT(process
()));
?
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
They are not equivalent. The timer causes the first request to be sent.
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Hi
are your sure this it's safe?
Quote:
Originally Posted by
wysota
Code:
Thread thread;
thread.moveToThread(&thread);
thread.start();
You use moveToThread when the thread (which execute run) is not ever created
But maybe i don't understand what do moveToThread and the signification of QObject thread affinity in Qt :o)
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
yan
Hi
are your sure this it's safe?
Yes.
Quote:
You use moveToThread when the thread (which execute run) is not ever created
It doesn't matter, as far as I know. It's all about just marking which thread will handle events for the object and its children.
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
wysota
It doesn't matter, as far as I know. It's all about just marking which thread will handle events for the object and its children.
Thanks for confirmation.
I investigate, and i understand all QObject have an affinity with a QThread and not the interfaced thread( that I believed), ans if you do
Code:
thread.moveToThread(&thread);
you can't call start() by signal/slot system to start a thread because the QThread eventloop don't run.
is right?
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
You can, but then you have to move the thread to itself after start() is executed - for example from a slot connected to the started() signal.
Re: Creating a QTcpSocket or a QTcpServer in a thread other than the main thread.
Quote:
Originally Posted by
wysota
You can, but then you have to move the thread to itself after start() is executed - for example from a slot connected to the started() signal.
ok thanks.
sorry for except subject