Reputation: 16359
I have a following situatuion.
Socket
objects are created in the main in a for
loop (the original problem has 1000 objects). Upon creation the start()
method is invoked.start()
creates a QTcpSocket
which tries to connect to some host.Socket
has slots which catch the connected()
signal from QTcpSocket and print some debug outputWhat happens is that chronologically first ALL the Socket
objects are created after which the sockets are started. Here is an example output of debug options:
1. Created Socket object 1
2. Invoked Socket object 1 start()
3. Created Socket object 2
4. Invoked Socket object 2 start()
5. Socket object 1 TcpSocket Connected
6. Socket object 2 TcpSocket Connected
Code:
//main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
for (int i=0; i<10; i++)
{
Socket *socket = new Socket();
qDebug() << "Socket object created";
socket->Start();
}
return a.exec();
}
//socket.cpp
Socket::Socket(QObject *parent)
: QObject(parent)
{}
void Socket::Start()
{
qDebug()<<"Start method invoked";
socket = new QTcpSocket(this);
connect(socket,SIGNAL(connected()), this, SLOT(on_connect()), Qt::DirectConnection);
socket->connectToHost("192.168.5.5",12345);
}
void Socket::on_connect()
{
QTcpSocket* socket = qobject_cast<QTcpSocket *>(QObject::sender());
qDebug() << socket->socketDescriptor() << " Connected.";
}
This is not the behavior I expected because the documentation states:
When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call. When this happens, the signals and slots mechanism is totally independent of any GUI event loop.
Question:
How to ensure the slots are executed "immediately" (not only after the loop in the main finishes) when the signal is emitted?
The only available solution (without introducing new threads) i currently see:
Drop the use of signals and slots in this case, and implement everything in the start
method. Something like this:
Socket::start(){
...
if(!tcpsocket->waitForConnected(200)) qDebug() << "Socket object X TcpSocket Connected"
...
}
Upvotes: 0
Views: 1509
Reputation: 48216
establishing the connection happens asynchronously (read connectToHost
will return immediately before it even checks whether the connection has already been established) and will notify your code using the signals that are triggered by events
these events are handled only in the event loop or when you call WaitForConnect (which will spin up it's own even loop only handling those events)
this means that the sequence you get is perfectly normal
Upvotes: 1
Reputation: 1082
Your slot is indeed triggered immediately when QTcpSocket
's signal connected()
is emitted.
However, connected()
is not emitted the moment you try to connect that socket to somewhere.
The documentation writes:
This signal is emitted after connectToHost() has been called and a connection has been successfully established.
The establish of a connection requires an event loop.
Upvotes: 5
Reputation: 5250
I don't think you can do that without introducing new threads, only solution is seems your solution.
Or using DirectConnection instead of leaving it empty (Which is AutomaticConnection and which is QueuedConnection in your case) may be a solution. But I don't think that it will work because you need to wait in order to run that slot. I'm not sure, just give it a try.
Upvotes: 0