如何在没有 UI 挂起的情况下将 QtcpSockets 连接到大约 100 个服务器?

Posted

技术标签:

【中文标题】如何在没有 UI 挂起的情况下将 QtcpSockets 连接到大约 100 个服务器?【英文标题】:How can I connect QtcpSockets to about 100 servers without a UI hang? 【发布时间】:2021-06-02 06:41:31 【问题描述】:

当我创建 100 个 QTcpSockets 以连接到每个服务器并调用 connectToHost() 函数时,QDialog 卡住了。有没有办法将 connectToHost() 部分作为后台作业运行?

因此,所有连接都已建立,但在尝试连接时(调用 connectToHost(),UI 处于“无响应”状态。

// 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());
    

每个 QTcpSocket 连接到服务器时挂起的对话框。:

所有QTcpSockets尝试连接服务器后:

【问题讨论】:

最简单的解决方案可能是在循环中嵌入QApplication::processEvents()。这将在每次迭代中处理排队的事件,以便它始终仅在一次连接尝试时挂起。如果这还不够,那么您必须考虑多线程,但这可能需要更多的努力。 @Scheff'sCat 感谢您的回复。当我从另一个线程尝试 connectToHost() 时,会生成“当无法从另一个线程启用或禁用 Socket 通知程序”调试消息,所以我按照上面的代码进行编码。 【参考方案1】:

耗时的任务不应该在主线程上运行。在这种情况下,有两种策略:

线程的使用。 划分子任务,每T秒分批执行一次。

在这种情况下,我认为第二个选项最好使用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());

【讨论】:

@eyllansec 使用 QTimer 实现,指的是如何使用您的 QTimeLine。不再有 UI 挂起。非常感谢您的想法!

以上是关于如何在没有 UI 挂起的情况下将 QtcpSockets 连接到大约 100 个服务器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 P/Invoke 的情况下从 c# 创建挂起的进程?

如何根据 cpu/内存使用情况或挂起的请求返回 503 服务器繁忙?

如何让主管重新启动挂起的工人?

在没有 Root 访问权限的情况下,Linux 可以在 CPL3(用户模式)下崩溃或挂起的情况? [关闭]

如何在不挂起的情况下返回并恢复我的应用程序?

C++/MFC - 防止挂起的子 (ActiveX) 控件冻结整个 UI?