ZBLOG

#include #include #include #include #include #include #include #include #include #include #include #include ...

在你提供的代码中,出现了QObject::moveToThread相关错误以及关于QSocketNotifier的问题。这个问题通常与Qt的对象在不正确的线程上下文中被创建或移动有关。具体来说,你不能将一个已经被创建的QTcpSocket对象从一个线程移动到另一个线程,因为Qt中的对象(特别是继承自QObject的类)只能在其创建时所在的线程内使用。

问题分析:

  1. QTcpSocket 对象: 你的代码尝试将通过 TcpClient::getInstance()->GetTcpSocket() 获取到的 QTcpSocket 移动到不同的线程。这是问题所在。因为这个 socket 对象是在主线程中创建的,所以直接调用 moveToThread() 会导致运行时错误。

  2. 线程间通信: 通常,网络操作应该放置在特定于工作的线程中,并且信号和槽机制可以帮助我们进行跨线程通信,而不是直接移动这些对象。

修复建议:

  • 不移动 QTcpSocket:确保所有网络操作都在它们原始创建的同一线程中执行。你可以选择将 socket 的使用放入 QThread 的 run() 方法中,而不是尝试将其移至不同的线程。

  • 使用信号和槽来处理事件:而不是让多个线程序直接访问 socket,可以通过信号和槽来触发心跳发送等操作。

下面是修正后的代码示例,避免了对 QTcpSocket 的移动,同时保留了多线程结构。

#include <QApplication>
#include <QTcpSocket>
#include <QByteArray>
#include <QDataStream>
#include <QDebug>
#include <QList>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <QFileInfo>
#include <QThread>
#include "protocolTool.h"
#include "tcpclient.h"
#include "mainwindow.h"

class MaintestServerStartThread : public QThread
{
public:
    void run() override
    {
        TcpClient::getInstance()->Start(); // Start TCP client here.
    }
};

class ThreadClientHeartbeatStart : public QThread
{
public:
    void run() override
    {
        while (true)
        {
            QTcpSocket *socket = TcpClient::getInstance()->GetTcpSocket();
            if (socket->state() == QAbstractSocket::ConnectedState) {
                TcpClient::getInstance()->SendHeartbeat(); // Send heartbeat from the main thread.
            }
            Sleep(1000);
        }
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    // Initialize and configure TcpClient instance
    TcpClient::getInstance();
    
    QString strIp = (argc > 1) ? argv[1] : "127.0.0.1";
    
    MainWindow w;
    w.show();

    // Connect signals and slots for handling UI updates based on TCP events.
    QObject::connect(TcpClient::getInstance(), SIGNAL(sigShowQroll_call()), roll_call, SLOT(slotShowQroll_call()));
    
    TcpClient::getInstance()->SetTcpConnectIp(strIp);

    // Create and start server starter thread
    MaintestServerStartThread* serverStarter = new MaintestServerStartThread();
    serverStarter->start();

    // Create and start heartbeat checker thread
    ThreadClientHeartbeatStart* heartbeatChecker = new ThreadClientHeartbeatStart();
    heartbeatChecker->start();

    return a.exec();
}

总结

  • 确保所有 QTcpSocket 及其相关函数都是在线程安全且适当的上下文下调用。
  • 避免在线程之间直接移动 QObject 对象,如网络连接等,这可能会导致状态不一致或崩溃。
  • 使用 Qt 的信号和槽机制以异步方式处理跨线程事件。

如果还有其他问题或需要进一步的信息,请随时询问!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=6632

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?