0

我创建了一个线程,其中包含一个QTcpServer接受任何传入连接的线程:

void Service::run() //Service class is a subclass of QThread
{
    server->listen(QHostAddress::LocalHost, ServicePortNo);
    // server is a private member of Service    

    while(server->waitForNewConnection(-1)){
        QTcpSocket *socket = server->nextPendingConnection();
        handle(socket); // This is a pure virtual function
    }
}

handle(QTcpSocket *socket)

// TimeDateService is subclass of Service
// implementation of pure virtual function handle()
void TimeDateService::handle(QTcpSocket *socket)
{
    (new TimeDateSocketHandler(socket))->Start();
}

注意TimeDateSocketHandler是的子类,SocketHandler本身SocketHandler是的子类,QThread如下所示:

void SocketHandler::run()
{
    if(!socket->waitForReadyRead(WAIT_TIMEOUT))
    {
        socket->disconnectFromHost();
        socket->close();
        return;
    }
    QByteArray request = socket->readAll();
    QByteArray response = Serve(request); // Serve is a pure virtual function
    socket->write(response);
    socket->waitForBytesWritten(WAIT_TIMEOUT);
    socket->disconnectFromHost();
    socket->close();
}

最后是TimeDateSocketHandler

QByteArray TimeDateSocketHandler::Serve(QByteArray request)
{
    QByteArray response;
    response.append(QTime::currentTime().toString().toUtf8());
    response.append(QString(SEPARATOR).toUtf8());
    response.append(QDate::currentDate().toString().toUtf8());
    return response;
}

主功能:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TimeDateService timedateService;
    //CalculatorService calculatorService;
    //RemoteCMDService remoteCMDService;

    timedateService.StartService();
    //calculatorService.StartService();
    //remoteCMDService.StartService();

    return a.exec();
}

main函数中,我启动了TimeDateService. 但是当我连接到服务器以检索时间和日期时,服务器会发送时间和日期,但是当TimeDateSocketHandler想要关闭套接字时程序崩溃:

QCoreApplication::sendEvent 中的 ASSERT 失败:“无法将事件发送到其他线程拥有的对象。当前线程 3998779bf0。接收器 ''(类型为 'QNat iveSocketEngine')在线程 39985efcd0 中创建”,文件 kernel\qcoreapplicio n.cpp ,第 494 行

谁能帮帮我,请问我该如何解决这个问题,非常感谢

4

1 回答 1

1

你的问题是这一行:

(new TimeDateSocketHandler(socket))->Start();

父“套接字”位于 TimeDateService 线程中,但子“套接字”将位于 TimeDateocketHandler 线程中。使用 Qt 事件循环时,父母和孩子应该在同一个线程中。

这是文档的相关部分:

所有线程都支持事件过滤器,但监控对象必须与被监控对象位于同一线程中。类似地,QCoreApplication::sendEvent()(与 postEvent() 不同)只能用于将事件分派到位于调用函数的线程中的对象。这是一个例子:

解决方案相对简单:

或者

  • Use signal and slots. This means emit a signal instead of direct invokation and then connect the other thread's corresponding slot.

    TimeDateSocketHandler *timeDateSocketHandler = new TimeDateSocketHandler(socket);

    connect(this, SIGNAL(socketHandled()), timeDateSocketHandler, SLOT(Start()));

    emit socketHandled();

or

  • Use a smart pointer (like QSharedPointer) instead of raw pointer

  • Move to the socket handling into the other thread.

于 2014-01-13T08:09:52.693 回答