Qt中一个socket对象只能在同一个线程使用
Qt在不同线程使用socket报错:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpServer(0x1538a748), parent’s thread is QThread(0x15380578), current thread is QThread(0x15388d20)
测试方法
1、创建一个新的类CSocketTest,继承QObject;
2、创建一个QThread的对象;
3、创建一个QTcpServer的对象;
4、在初始化函数中,调用new QTcpServer,然后在connect的槽函数中调用new QTcpServer(子线程);
测试代码
CSocketTest的头文件
包含头文件:
QThread
QTcpServer
定义变量:
private:
QThread m_threadTest;
QTcpServer *m_tcpServer;
定义初始化函数:
void init();
定义信号,槽:
signals:
void notifySocketTest();
public slots:
void onNotifySocketTest();
CSocketTest的cpp文件
构造函数,使用moveToThread关联类与线程
CSocketTest::CSocketTest(QObject *parent) : QObject(parent)
{
m_threadTest.setObjectName(“socketThread”);
moveToThread(&m_threadTest);
}
void CSocketTest::init()
{
m_threadTest.start();
connect(this,SIGNAL(notifyScreenShot()),this,SLOT(SlotLaunchScreenShot()),Qt::QueuedConnection);
qDebug()<<"======= SlotLaunchScreenShot init : "<<QThread::currentThreadId();
#if 0
m_tcpServer = new QTcpServer();
#endif
emit notifyScreenShot();
}
void CSocketTest::SlotLaunchScreenShot()
{
#if 1
m_tcpServer = new QTcpServer();
#endif
int port = 8888; //获得端口号
if(!m_tcpServer->listen(QHostAddress::Any, port))
{
qDebug()<<“QT网络通信”, “服务器端监听失败!”;
}
qDebug()<<"======= SlotLaunchScreenShot m_tcpServer : "<<QThread::currentThreadId();
}
在main函数中调用这个init函数
#include “csockettest.h”
int main(int argc, char *argv[])
{
qDebug()<<"======= SlotLaunchScreenShot main : "<<QThread::currentThreadId();
CSocketTest::getInstance().init(); //其中CSocketTest::getInstance()是使用单例创建类的对象
return 0;
}
以上两个#if #endif,
第一种情况:是在主线程中new QTcpServer(),第二种情况:是在子线程中用new QTcpServer();
若是第一种情况,此时在子线程又用到了这个这个socket对象,如果是再主线程new的socket对象,则会报上面那个错误,该错误不会影响整个程序运行,但是不能正常使用socket对象。
若是第二种情况,则可以正常使用该socket对象。
说明:若是new socket对象在主线程,使用socket对象也在主线程,也可以正常使用该socket;
结论:在Qt中一个socket对象,只能在同一个线程中new以及使用;若是跨线程使用了socket对象,则无法正常使用该socket对象