前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt 线程中使用socket(勘误)

Qt 线程中使用socket(勘误)

作者头像
用户5908113
发布2019-09-09 17:51:52
1.2K0
发布2019-09-09 17:51:52
举报
文章被收录于专栏:Pou光明Pou光明

之前写过两篇关于qt线程中使用socket的文章,昨天有小伙伴看了文章之后和我讨论,然后我发现有一篇文章有问题,今天特地更正一下,误导了之前的小伙伴表示歉意。

Qt中将socket放到线程中运行目前我知道比较好的方式还是使用MoveToThread。不过要注意的是只有slot_initSocket()槽中的函数是运行在新的线程中的。就像继承QThread重新实现run()函数一样,只有run()里面的是运行在线程中一样。

程序示例:

代码语言:javascript
复制
    m_socketClient.moveToThread(&m_thread);

    connect(&m_thread, SIGNAL(started()), &m_socketClient, SLOT(slot_initSocket()));

    m_thread.start();

经过Qt封装的socket我们使用起来非常方便,有数据到来可以读取后就会触发槽函数,如果使用继承QThread重新实现run()函数的方式,就会不可避免的遇到无法舒服使用信号和槽的情况。而使用MoveToThread则可以规避上面的问题——我们将socket的初始化放到slot_initSocket()函数中,则socket的初始化则是在线程中完成的,那么对应里面信号和槽的连接也是运行在新线程中的。

程序示例:

connect(mp_clsTcpSocket,SIGNAL(readyRead()),this,SLOT(slot_recvServerData()));

经过上面的操作,我们的socket就可以运行在线程中了。Qt官方也非常推荐使用moveToThread函数。

示例程序是之前socket拆包、处理粘包程序的修改,大家有兴趣可以了解下。服务器端是接收图片、客户端发送图片,下面程序是客户端部分。

老规矩,贴下程序,方便理解:

一、继承QObject的socket 客户端程序

代码语言:javascript
复制
MySocketClient::MySocketClient(QObject *parent) : QObject(parent)
{
    mp_clsTcpSocket = new QTcpSocket(this);
}

void MySocketClient::slot_recvServerData()
{
    QByteArray data = mp_clsTcpSocket->readAll();

    qDebug() << "------------" << data;
    qDebug() << "socket recv thread id:" << QThread::currentThreadId();}

void MySocketClient::slot_writeData(QByteArray str)
{
    mp_clsTcpSocket->write(str);
}

void MySocketClient::slot_initSocket()
{
    qDebug() << "socket thread id:" << QThread::currentThreadId();

    mp_clsTcpSocket->connectToHost("127.0.0.1",8002);
    mp_clsTcpSocket->waitForConnected(1000);

    connect(mp_clsTcpSocket,SIGNAL(readyRead()),this,SLOT(slot_recvServerData()));
}

二、主线程函数

①构造函数中使用moveToThread

代码语言:javascript
复制
 m_socketClient.moveToThread(&m_thread);
    connect(&m_thread, SIGNAL(started()), &m_socketClient, SLOT(slot_initSocket()));
    m_thread.start();

    connect(this, SIGNAL(signal_sendPicrure(QByteArray)),
            &m_socketClient,SLOT(slot_writeData(QByteArray)));
            

②主Ui线程通过信号和槽使用线程中的socket发送数据

代码语言:javascript
复制
void Widget::on_pbn_send_clicked()
{
    QString str = "i am from server of main ui";
    emit (signal_sendData(str));
}

三、程序运行效果:

Server 的初始化在新的线程中(1),接受客户端连接也在新的线程中(2)。

Client 的初始化在新的线程中(1),接收服务器数据也在新的线程中(2)。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档