Qt笔记-QTcpSocket跨线程调用(官方推荐方法,非百度烂大街方法)
Posted IT1995
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt笔记-QTcpSocket跨线程调用(官方推荐方法,非百度烂大街方法)相关的知识,希望对你有一定的参考价值。
TCP服务端的经典案例中有个例子,就是当收到TCP客户端连接后,线程池直接开一个线程然后把这个socket指针传到线程里面,依靠新开的线程进程业务处理。
但在Qt里面使用这个方式后,会报一个QTcpSocket不能跨线程调用的问题。
问题描述是这样的:
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
查了下百度,都是n年前的技术(本博文写于2021-08-11 09:15:25,此博文发布到网上应该是1个月以后,笔记太多了,每星期公布6篇笔记),用信号与槽机制将业务处理放到新线程中,TCP操作用信号让以前的线程发送数据,通过这种方式解决问题!但如果这样做,代码就不够优雅了,甚至还有点烂。一个新技术框架和老技术做对比,应该是取其精华去其糟粕,而不是越来越复杂。不然这个新技术将毫无意义。
花了半天时间查阅了官方资料,最后得出了QTcpSocket跨线程调用的方式。
首先继承QTcpServer重写incomingConnection(qintptr handle)
当这个handle此时套接字的描述符号。把这个传给线程,子线程生成一个QTcpScoket然后利用setSocketDescriptor使得这个socket获得到收发数据的能力。
实例如下:
QTcpServer相关:
void HttpsServer::incomingConnection(qintptr socketDescriptor)
{
QThreadPool::globalInstance()->start(new HttpsThread(socketDescriptor));
}
QRunnable相关:
HttpsThread::HttpsThread(qintptr descriptor)
{
m_socketDescriptor = descriptor;
}
这个m_socketDescriptor直接为int型就可以了。
这样run()中调用setSocketDescriptor,进行读写操作就不会有跨线程的问题了。
void HttpsThread::run()
{
QTcpSocket tcpSocket;
if(!tcpSocket.setSocketDescriptor(m_socketDescriptor)) {
qDebug() << "tcpSocket.setSocketDescriptor(m_socketDescriptor) failed";
return;
}
tcpSocket.write("Hello Wold");
tcpSocket.disconnectFromHost();
tcpSocket.waitForDisconnected();
}
以上是关于Qt笔记-QTcpSocket跨线程调用(官方推荐方法,非百度烂大街方法)的主要内容,如果未能解决你的问题,请参考以下文章
Qt笔记-QTcpSocket中调用readAll要注意的地方(Java中RestTemplate和Qt配合要注意的地方)
Qt笔记-QTcpSocket中调用readAll要注意的地方(Java中RestTemplate和Qt配合要注意的地方)
从来自 QTcpSocket 的数据流中连续运行复杂算法的最佳 Qt 线程解决方案是啥?