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"
...
}
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