前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt线程中使用Socket客户端通信

Qt线程中使用Socket客户端通信

作者头像
用户5908113
发布2019-07-29 11:15:32
4.5K0
发布2019-07-29 11:15:32
举报
文章被收录于专栏:Pou光明Pou光明

在编写一般程序中,通常将通信部分与数据处理部分单独放到一个线程或进程(Python由于GIL锁需要使用进程),这样可保证程序的快速响应,数据处理不会对其他部分造成影响。

在Qt中使用线程有两种方式:一种是继承QThread,重新实现run()函数。此时要注意,只有run()函数里面的才是单独运行到线程中的。通常在run()函数中使用while()循环或for循环与队列配合,让线程一直处理请求。另一种是使用moveToThread()函数将对象移到子线程中,moveToThread()函数之后再做说明,本次主要说明使用QThread时遇到的问题。

这是传说中的UI。。。 ~ ~。。。

一些程序:

#ifndef THREADSOCKET_H

#define THREADSOCKET_H

#include <QThread>

#include <QTcpSocket>

class ThreadSocket : public QThread

{

Q_OBJECT

public:

ThreadSocket();

void start_thread();

public slots:

void slot_readmesg();

void slot_WritMsgToServer(QString str);

protected:

void run();

private:

QTcpSocket *mp_clsTcpSocket;

bool couldReadData;

};

#endif // THREADSOCKET_H

#include "threadsocket.h"

#include <QDebug>

ThreadSocket::ThreadSocket():

QThread(),

couldReadData(false)

{

qDebug() << "parent this id" << this;

}

void ThreadSocket::start_thread()

{

if(!this->isRunning())

this->start();

}

void ThreadSocket::slot_readMsgFromServer()

{

couldReadData = true;

QByteArray buffer = mp_clsTcpSocket->readAll();

qDebug() <<"msg:"<< buffer;

}

void ThreadSocket::slot_WritMsgToServer(QString str)

{

mp_clsTcpSocket->write(str.toLatin1());

}

void ThreadSocket::run()

{

mp_clsTcpSocket = new QTcpSocket();

mp_clsTcpSocket->connectToHost("192.168.18.77",2115);

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

if (mp_clsTcpSocket->waitForConnected(1000))

{

qDebug() << "connect success !";

}else{

qDebug() << "connect faild !";

}

while(1)

{

qDebug() << "__________________";

mp_clsTcpSocket->write("test\n");

mp_clsTcpSocket->flush();

qDebug() << "couldReadData" << couldReadData;

if (true == couldReadData)

{

QByteArray buffer = mp_clsTcpSocket->readAll();

qDebug() <<"receive server msg:"<< buffer;

couldReadData = false;

}

sleep(1);

②// exec();

}

}

简单说下程序构成:所贴代码主要是线程中的socket接收与发送测试代码。主UI中有两个按钮,一个是启动线程,另一个是在通过信号槽向服务器发送数据。

在run()函数中实例化客户端,注意不要传入this指针,否则会报如下错误:QObject: Cannot create children for a parent that is in a different thread.【QObject:无法为位于不同线程中的父级创建子级。】

这样客户端就存在与子线程中,同样在run()中连接信号和槽。注意此时的this是父类的this,即信号与槽位于不同的线程。这是第一个值得注意的地方。

第二该测试中,需要在客户端write()后加flush(),否则客户端无法发送数据。这是第二个需要注意的地方。

第一种测试:

运行该测试程序,可以在run()中向服务器发送数据,但是无法在主UI通过信号和槽的方式向服务器发送数据。点击Send按钮,报错如下:QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread.【QSocketNotifier:无法从另一个线程启用或禁用套接字通知程序】。服务器向客户端发送数据,客户端接收不到,connect()函数返回True,说明信号与槽连接成功。这是上述测试程序的运行结果。

第二种测试:

在sleep(1)后加入 exec()函数,while()循环只执行一次,客户端槽函数可以接收服务器发出的数据。但在主UI中依然无法向服务器发送数据。

这次的内容只描述两种测试结果,接下来的其他内容将逐步剖析这些情况的原因。

一起学习,共同进步。我们都是奋斗者!

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

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

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

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

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