How can I connect QtcpSockets to about 100 servers without a UI hang?

52 Views Asked by At

How can I connect QtcpSockets to about 100 servers without a UI hang?

When I create 100 QTcpSockets to connect to each server and call the connectToHost() function, the QDialog stuck. Is there a way to run the connectToHost() part as a background job?

As a result, all connections are made, but while trying to connect (call connectToHost() the UI is in 'No Response' state.

// onConnectToICPMC is the slot function connected to the dialog button pressed signal
void WidgetUploadFile::onConnectToICPMC()
{
    // m_tcpClients is a QVector containing a custm QObject Class that manages QTcpSocket
    for(int i = 0; i < m_tcpClients.size(); ++i)
    {
        if(m_tcpClients.at(i)->state() != QAbstractSocket::ConnectedState)
        {
            m_tcpClients.at(i)->connectToServer(); // Call the connectToHost() function of QTcpSocket.
        }
        emit sendConnProgBarUpdate(i+1);
        emit sendCurrentSockLog(m_tcpClients.at(i)->ipAddress(), m_tcpClients.at(i)->state());
    }
}

A dialog that hangs while each QTcpSocket connects to the server.:
A dialog that hangs while each QTcpSocket connects to the server.

After all QTcpSockets try to connect to the server:
After all QTcpSockets try to connect to the server

1

There are 1 best solutions below

1
eyllanesc On BEST ANSWER

Time-consuming tasks should not be run on the main thread. In that case there are 2 strategies:

  • Use of threads.
  • Divide into subtasks and execute in parts every T seconds.

In this case I think the second option is the best using QTimeLine.

*.h

private:
   void handleFrameChanged(int i);
   QTimeLine timeLine;

*.cpp

{
    // constructor
    timeLine.setRange(0, m_tcpClients.size()-1);
    connect(&timeLine, &QTimeLine::frameChanged, this, &WidgetUploadFile::handleFrameChanged);
}

void WidgetUploadFile::onConnectToICPMC()
{
    timeLine.start();
}

void WidgetUploadFile::handleFrameChanged(int i){
    auto client = m_tcpClients.at(i);
    if(client->state() != QAbstractSocket::ConnectedState){
        client->connectToServer();
    }       
    emit sendConnProgBarUpdate(i + 1);
    emit sendConnProgBarUpdate(client->ipAddress(), client->state());
}