qtcpsocket断开_2020-05-06 QT子线程使用QTcpSocket连接服务器

qtcpsocket断开_2020-05-06 QT子线程使用QTcpSocket连接服务器为什么要是用多线程?多线程的使用主要是为了处理比较耗时的过程。多线程的实现可以通过两种方式实现分别是:1.继承QThread实现多线程2.继承QObject实现多线程(由于继承QObject的多线程实现方法更加灵活,Qt官方推荐使用该方法实现多线程)。这里将采用第二种方式实现多线程多线程实现过程1.创建一个继承于QObject的自定义线程类,用来处理比较耗时的功能。相关函数:voidsetFla…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

为什么要是用多线程?

多线程的使用主要是为了处理比较耗时的过程。多线程的实现可以通过两种方式实现

分别是:1.继承QThread实现多线程2.继承QObject实现多线程(由于继承QObject的多线程实现方法更加灵活,Qt官方推荐使用该方法实现多线程)。这里将采用第二种方式实现多线程

多线程实现过程

1.创建一个继承于QObject的自定义线程类,用来处理比较耗时的功能。

相关函数:

void setFlag(bool flag = true); //用于设置线程是否启动

void ConnectServer();//用于连接到服务器

槽函数:注意:槽函数应该用“private slots:”来修饰

void dowork();//线程处理函数

void ConnectedSuccess();//用来响应QTcpSocket的conneted()信号

void readData();//用来响应QTcpSocket的readyRead()信号

信号函数:注意:信号函数应该用 “signals:”来修饰

void signal_connectsuccess(QString)//用来向主线程发送链接成功信息

void signal_back(QString)//用来向主线程发送从服务器获取的数据

2.在主线程中创建一个子线程

QThread *mThread = new QThread(this);

3.创建一个自定义线程对象

TcpSocketThread *mTcpSocketThread = new TcpSocketThread ();

注意:这里创建的对象不能指定父对象,因为不能移动已经具有父类的对象,mThread可以看做是mTcpSocketThread 的父类

4.将子线程类对象移动到子线程容器中

mTcpSocketThread .moveToThread(mThread);

5.连接主线程与子线程之间的信号和槽函数(这里用的是QT4.8.6,QT5版本的connect函数则不同)

主线程——>子线程

connect(this,SIGNAL(StartThread()),mTcpSocketThread, SLOT(doWork()));

子线程——–>主线程

connect(mTcpSocketThread,SIGNAL(signal_connectsuccess(QString)),this,SLOT(slot_handle_state(QString)));

connect(mTcpSocketThread,SIGNAL(signal_back(QString)),this,SLOT(slot_handle_data(QString)));

使用connect不成功有可能是如下原因

这里需要注意 信号函数和槽函数的参数列表应该一致

使用信号槽,需要在类中声明 Q_OBJECT宏

槽函数应该用“private slots:”来修饰

信号函数应该用 “signals:”来修饰

6.子线程使用完毕应该及时回收并销毁

mThread->quit();

mThread->wait()

相关代码

主线程类:tcpclient.h

#ifndef TCPCLIENT_H

#define TCPCLIENT_H

#include

#include

#include

#include

#include

#include “ui_tcpclient.h”

#include “tcpsocketthread.h”

class TCPClient : public QWidget

{

Q_OBJECT

public:

explicit TCPClient(QWidget *parent = 0, Qt::WFlags flags = 0);

~TCPClient();

private:

Ui::TCPClientClass ui;

TCPSocketThread *mTcpSocketThread; //子线程

QThread *mThread; //线程管理器

private slots:

//处理链接状态信号

void slot_handle_state(QString);

//处理数据信号

void slot_handle_data(QString);

private slots:

//链接服务器

void on_Btn_Connect_clicked();

//启动线程

void on_Btn_start_clicked();

//断开链接

void on_Btn_DisConnect_clicked();

signals:

void StartThread();

};

#endif // TCPCLIENT_H

主线程类:tcpclient.cpp

#include “tcpclient.h”

TCPClient::TCPClient(QWidget *parent, Qt::WFlags flags)

: QWidget(parent, flags)

{

ui.setupUi(this);

//创建子线程

mTcpSocketThread = new TCPSocketThread();

//创建线程管理

mThread = new QThread();

//将子线程移动到线程管理器中

mTcpSocketThread->moveToThread(mThread);

//信号槽事件

connect(this,SIGNAL(StartThread()),mTcpSocketThread, SLOT(doWork()));//开启子线程

connect(mTcpSocketThread,SIGNAL(signal_connectsuccess(QString)),this,SLOT(slot_handle_state(QString)));//处理子线程信号

connect(mTcpSocketThread,SIGNAL(signal_back(QString)),this,SLOT(slot_handle_data(QString)));

}

TCPClient::~TCPClient()

{

}

void TCPClient::on_Btn_Connect_clicked()

{

//若线程正在运行,返回

if(mThread->isRunning()==true) return;

//线程状态设置为开启

mTcpSocketThread->setFlag(false);

//开启线程

mThread->start();

//启动了线程,并未进入线程

//发送信号,进入线程

emit StartThread();

ui.Lbl_ClientState->setText(“Connected Success!”);

}

void TCPClient::on_Btn_start_clicked()

{

}

void TCPClient::on_Btn_DisConnect_clicked()

{

//若线程已关闭,返回

if(mThread->isRunning()!=true) return;

//线程状态设置为关闭

mTcpSocketThread->setFlag(true);

mThread->quit();

mThread->wait();

ui.Lbl_ClientState->setText(“Not Connected”);

}

void TCPClient::slot_handle_state(QString str)

{

ui.Lbl_ClientState->setText(str);

}

void TCPClient::slot_handle_data(QString str)

{

ui.textEdit->append(str);

}

自定义线程类 tcpsocketthread.h

#ifndef TCP_SOCKET_THREAD

#define TCP_SOCKET_THREAD

#include

#include

#include

#include

#include

#include

#include

enum MessageType{ConnectRequest,ConnectSuccess,DisConnect,DataRequest/*……….*/};//消息请求类型

class TCPSocketThread :public QObject

{

Q_OBJECT

public:

explicit TCPSocketThread(QObject *parent = 0);

~TCPSocketThread(void);

private:

bool isStop; //线程是否停止

bool isConnected; //服务器是否链接

QTcpSocket *mTcpSocket;

quint16 nextBlockSize;

public:

//设置状态

void setFlag(bool flag = true);

private:

//链接服务器

void ConnectServer();

private slots:

//线程处理函数

void doWork();

//链接成功

void ConnectedSuccess();

//获取数据

void readData();

signals:

//链接状态信号

void signal_connectsuccess(QString);

//数据信号

void signal_back(QString);

};

#endif

自定义线程类 tcpsocketthread.cpp

#include “tcpsocketthread.h”

TCPSocketThread::TCPSocketThread(QObject *parent /* = 0 */):QObject(parent)

{

isStop = false;

isConnected = false;

mTcpSocket = new QTcpSocket(this);

nextBlockSize = 0;

connect(mTcpSocket,SIGNAL(connected()),this,SLOT(ConnectedSuccess()));

connect(mTcpSocket,SIGNAL(readyRead()),this,SLOT(readData()));

}

TCPSocketThread::~TCPSocketThread(void)

{

}

void TCPSocketThread::doWork()

{

while(!isStop)

{

if(!isConnected) ConnectServer();

QByteArray data;

QDataStream out(&data,QIODevice::WriteOnly);//======out

out<

mTcpSocket->write(data);

mTcpSocket->waitForReadyRead();

}

}

void TCPSocketThread::setFlag(bool flag)

{

isStop = flag;

}

void TCPSocketThread::ConnectServer()

{

QString ip = “127.0.0.1”;

qint16 port = 40404;

mTcpSocket->connectToHost(QHostAddress(ip),port);

mTcpSocket->waitForConnected();

}

void TCPSocketThread::ConnectedSuccess()

{

isConnected = true;

QString str = “connected success!”;

emit signal_connectsuccess(str);

}

void TCPSocketThread::readData()

{

//这里的代码都无关紧要

//…….

emit signal_back(str);

//…….

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/197717.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关于HashMap扩容机制

    关于HashMap扩容机制HashMap的底层有数组+链表(红黑树)组成,数组的大小可以在构造方法时设置,默认大小为16,数组中每一个元素就是一个链表,jdk7之前链表中的元素采用头插法插入元素,jdk8之后采用尾插法插入元素,由于插入的元素越来越多,查找效率就变低了,所以满足某种条件时,链表会转换成红黑树。随着元素的增加,HashMap的数组会频繁扩容,如果构造时不赋予加载因子默认值,那么负载因子默认值为0.75,数组扩容的情况如下:1:当添加某个元素后,数组的总的添加元素数大于了数组长度*0.75(默认,也可自己设

    2022年6月25日
  • ettercap 图形界面遇无线网卡报错[通俗易懂]

    ettercap 图形界面遇无线网卡报错[通俗易懂]ettercap0.8.2copyright2001-2015EttercapDevelopmentTeamERROR:9,错误的文件描述符[/build/ettercap-W54WVV/ettercap-0.8.2/src/ec_network.c:source_init:245]libnet_init:unknownphysicallayertype0…

    2022年6月28日
  • 反向传播(BPTT)与循环神经网络(RNN)文本预测

    反向传播(BPTT)与循环神经网络(RNN)文本预测反向传播(BPTT)与RNN文本预测实战本文介绍简单RecurrentNeuralNetworks(RNN)的基本训练算法BACKPROPAGATIONTHROUGHTIME(BPTT),并用python2.7实现RNN的文本预测。

    2022年6月23日
  • python编程新手常犯的错误_python数组从0还是1

    python编程新手常犯的错误_python数组从0还是1在下面的例子中,希望做到的是数组a,b中元素大于3的置为1,其余为0。应该先做置0操作。程序:importnumpyasnpa=[1,2,2,3,4,5]a=np.array(a)b=[1,2,2,3,4,5]b=np.array(b)#错误的例子a[a>3]=1a[a<=3]=0print(‘a’,a)b[b<=3]=0b[b>3]=1print(‘b’,b)输出:a[00000

    2022年8月13日
  • java jbpm工作流_jbpm工作流

    java jbpm工作流_jbpm工作流一、JBPM(javabusinessprocessmanager)1、工作流管理流程O—>定义工作流(使用流程设计器生成,png和xml文件,分别面向用户和系统)—>执行工作流(核心对象:流程引擎ProcessEngine)—>连接数据库(jbpm18张表,jbpm4_deploymen,jbpm4_deployprop,jbpm4_execution,jbp…

    2022年9月10日
  • 深入理解卷积层,全连接层的作用意义「建议收藏」

    深入理解卷积层,全连接层的作用意义「建议收藏」有部分内容是转载的知乎的,如有侵权,请告知,删除便是,但由于是总结的,所以不一一列出原作者是who。再次感谢,也希望给其他小白受益。首先说明:可以不用全连接层的。理解1:卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。因为用到了所有的局部特征,所以叫全连接。理解2:从卷积网络谈起,卷积网络在形式上有一点点像咱们正在召开的“人民代表大会制度”。卷积核的个数相当于候选人,…

    2022年9月19日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号