[英]Access QTcpSocket from another thread (child thread)
我创建了一个包含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失败:“无法将事件发送到其他线程所拥有的对象。在线程39985efcd0中创建了当前线程3998779bf0.Receiver(类型为'QNat iveSocketEngine')”,文件kernel \\ qcoreapplicatio n.cpp ,第494行
任何人都可以帮我吗,我该如何解决这个问题,非常感谢
您的问题是这一行:
(new TimeDateSocketHandler(socket))->Start();
父“套接字”位于TimeDateService线程中,而子“套接字”位于TimeDateocketHandler线程中。 使用Qt事件循环时,父级和子级应该在同一线程中。
这是文档的相关部分:
所有线程均支持事件过滤器,但限制是监视对象必须与被监视对象位于同一线程中。 同样,QCoreApplication :: sendEvent()(与postEvent()不同)只能用于将事件调度到存在于调用该函数的线程中的对象。 这是一个例子:
解决方案相对简单:
您可以使用QMetaObject的invokeMethod方法直接调用该方法。 您将需要使用排队连接来在单独的线程中触发插槽。
QMetaObject :: invokeMethod(新的TimeDateSocketHandler(socket),SLOT(Start()),Qt :: QueuedConnection);
要么
使用信号和插槽。 这意味着发出信号而不是直接调用,然后连接另一个线程的相应插槽。
TimeDateSocketHandler * timeDateSocketHandler = new TimeDateSocketHandler(socket);
connect(this,SIGNAL(socketHandled()),timeDateSocketHandler,SLOT(Start()));
发出socketHandled();
要么
使用智能指针(如QSharedPointer)代替原始指针
移动到另一个线程的套接字处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.