在Qt中,QSocketNotifier应该在创建它的线程中被启用和禁用。由于你在不同的线程中使用QTcpSocket,这会导致出现QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread的错误。
要解决这个问题,你可以将QTcpSocket对象放在主线程中,并通过信号与槽机制与其他线程进行通信。下面是一个修正的示例:
#include <QApplication>
#include <QTcpSocket>
#include <QThread>
#include <QDebug>
#include "tcpclient.h"
#include "mainwindow.h"
class MaintestServerStartThread : public QThread
{
public:
    void run() override {
        TcpClient::getInstance()->Start();
    }
};
class ThreadClientHeartbeatStart : public QThread
{
public:
    void run() override {
        while (true) {
            QTcpSocket *socket = TcpClient::getInstance()->GetTcpSocket();
            if (socket->state() == QAbstractSocket::ConnectedState) {
                // Socket 连接正常
                TcpClient::getInstance()->SendHeartbeat();
            }
            Sleep(1000);
        }
    }
};
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    TcpClient::getInstance(); // Initialize the TCP client instance
    QString strIp = argc > 1 ? argv[1] : "127.0.0.1";
    
    MainWindow w;
    w.show();
    // Start server thread
    MaintestServerStartThread* serverStarter = new MaintestServerStartThread();
    serverStarter->start();
    // Start heartbeat thread
    ThreadClientHeartbeatStart* heartbeatChecker = new ThreadClientHeartbeatStart();
    heartbeatChecker->start();
    return a.exec();
}
注意事项:
- QObject 的子类:如果你的 - TcpClient类是- QObject的子类,请确保它只能由创建它的线程访问。
- 信号与槽:保持信号与槽机制,以便主线程可以接收到从网络层发送过来的数据或心跳信息。如果需要跨线程操作,可以使用 Qt 的 - signal/slot机制来处理。
- 多线程中的 QObject:如果你要在多个线程间共享某些 QObject 实例,最好避免直接调用其方法,而是通过信号和槽来触发相应的行为。 
以上修改确保了所有 socket 操作都在同一个线程中进行,从而避免了您遇到的问题。
内容由零声教学AI助手提供,问题来源于学员提问


 
                             
         
        
 
         
         
         
         
         
         
        
 
                 
                 
                 
                 
                 
                 
                 
                 
                