Qt的Tcp服务器多线程编程-附带代码展示

2023-11-17

Qt的Tcp服务器多线程编程-附带代码展示

该程序主要实现tcp服务器如何使用多线程的方式来连接多个客户端,此文章没有实现客户端的多线程编程。
创建子线程时需要注意的点:
1、子线程与主线程之间交互数据时,应采用信号槽的方式
2、子线程中实例化的对象,不应出现在其他线程当中
3、子线程需加入QThread::exec()事件循环函数
4、子线程的销毁关联窗口的销毁信号,调用exit()、quit()、deleteLater()
期间所遇到的问题:
1、之前的思路是想在子线程当中去监听客户端的连接以及数据处理,后面发现在子线程中关联的readyRead()信号始终无法接收到,随后改为在主线程中监听客户端的连接,在子线程中只处理数据
2、子线程对象的实例化也需要注意,需在newConnection()连接的槽函数进行连接,否则客户端断开与服务端的连接后,再次连接时可能无法通信

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "mytcpserver.h"
#include <QTcpServer>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  MainWindow(QWidget *parent = nullptr);
  ~MainWindow();

  myTcpServer *mytcp_t;
  QTcpServer *server;

  QTcpServer *server_com2;
  tcp_server1 *mytcp_com2;
  int port;

private:
  Ui::MainWindow *ui;

private slots:
  void on_bt_listen_clicked();

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkInterface>

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  foreach (QHostAddress info, QNetworkInterface::allAddresses()) {
      qDebug()<<info.toString();
      if(info.toString().size() == 12)
        {
          ui->ld_severip->setText(info.toString());
        }
  }

}

MainWindow::~MainWindow()
{
  delete ui;
}


void MainWindow::on_bt_listen_clicked()
{

  qDebug()<<QString::fromLocal8Bit("主线程地址:")<<QThread::currentThreadId();

  port = ui->ld_port->text().toShort();

  //实例服务器对象
  server = new QTcpServer();
  server_com2 = new QTcpServer();
  //监听端口
  server->listen(QHostAddress::Any, port);
  server_com2->listen(QHostAddress::Any, port+2);
  //连接新连接信号,关联线程的启动
  connect(server, &QTcpServer::newConnection, this, [=]{
      mytcp_t = new myTcpServer(server);
      //启动子线程
      mytcp_t->start();
    });
  connect(server_com2, &QTcpServer::newConnection, this, [=]{
      mytcp_com2 = new tcp_server1(server_com2);
      mytcp_com2->start();
    });
  //线程的销毁
  connect(this, &MainWindow::destroyed, this, [=]{
      mytcp_t->exit();
      mytcp_t->quit();
      mytcp_t->deleteLater();

      mytcp_com2->exit();
      mytcp_com2->quit();
      mytcp_com2->deleteLater();
    });

}

mytcpserver.h

#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>

#include "dataprocess.h"

class myTcpServer: public QThread
{
  Q_OBJECT
public:
  explicit myTcpServer(QTcpServer *parent);

  void run() override;

private:

  void WriteCmd(int _cmd);

signals:

protected:
  QTcpServer *server;
  QTcpSocket *socket;
  QString rcv;

  dataprocess *anysis_data;

public slots:
  void getAddrlist(QStringList addr_list);

};

class tcp_server1: public QThread
{
  Q_OBJECT
public:
  explicit tcp_server1(QTcpServer *parent);

  void run() override;

protected:
  QTcpServer *server;
  QTcpSocket *socket;
  QString rcv;

};

#endif // MYTCPSERVER_H

mytcpserver.cpp

#include "mytcpserver.h"
#include <QDebug>
#include <QThread>
QString cmd_reset = "AT+RESET\r\n";

myTcpServer::myTcpServer(QTcpServer *parent)
{
  server = parent;
}

void myTcpServer::run()
{

      bool res = false;
      qDebug()<<QStringLiteral("子线程地址:")<<QThread::currentThreadId();

      socket = new QTcpSocket();
      socket = server->nextPendingConnection();

      anysis_data = new dataprocess;

      res = connect(socket, &QTcpSocket::readyRead, [=](){
          int cnt = 0;
          rcv = socket->readAll();
          //DataAnysis(rcv);
          cnt = anysis_data->DataAnysis(rcv);
          WriteCmd(cnt);
          qDebug()<<"have already receive data";
      });
      connect(socket, &QTcpSocket::disconnected, [=](){
          qDebug()<<"Disconnected";
        });
      qDebug()<<res;

      // 进入事件循环
      exec();
}


void myTcpServer::WriteCmd(int _cmd)
{
  switch(_cmd)
  {
      case 1:
        break;
      case 2:
        break;
      case 3:
        break;
    }
}

void myTcpServer::getAddrlist(QStringList addr_list)
{
  qDebug()<<addr_list[0];
}






tcp_server1::tcp_server1(QTcpServer *parent)
{
  server = parent;
}

void tcp_server1::run()
{
  bool res = false;
  qDebug()<<QStringLiteral("子线程地址:")<<QThread::currentThreadId();

  socket = new QTcpSocket();

  socket = server->nextPendingConnection();

  res = connect(socket, &QTcpSocket::readyRead, [=](){
      rcv = socket->readAll();
      //DataAnysis(rcv);
      qDebug()<<"have already receive data";
  });
  connect(socket, &QTcpSocket::disconnected, [=](){
      qDebug()<<"Disconnected";
    });
  qDebug()<<res;

  // 进入事件循环
  exec();
}

dataprocess.h

#ifndef DATAPROCESS_H
#define DATAPROCESS_H

#include <QObject>
#include <QString>
#include <QTcpSocket>


class dataprocess: public QObject
{
  Q_OBJECT
public:
  explicit dataprocess();
  //~dataprocess();

  int DataAnysis(QString str);

private:
  QTcpSocket *socket;
  QStringList strlist;

signals:
  void moveAddrlist(QStringList addrlist);

};

#endif // DATAPROCESS_H

dataprocess.cpp

#include "dataprocess.h"

dataprocess::dataprocess()
{

}

int dataprocess::DataAnysis(QString str)
{
    if(str == "AT-RESET:OK\r\n")
    {
        qDebug()<<"Module Init Success";
    }
    else if(str == "AT-LOGO:BT11P31\r\n")
    {
        qDebug()<<"Init output Success";
    }
    else if(str == "AT-SSCANN:OK\r\n")
    {
        qDebug()<<"Scann cmd send";
    }
    else if(str.contains("AT-SCANI:OK"))
    {

    }
    else if(str.contains(QString("AT-SCANRP:")))
    {
        strlist.push_back(str.mid(10, 12));
        emit moveAddrlist(strlist);
        qDebug()<<strlist[0];
    }
    else
    {

    }
    return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt的Tcp服务器多线程编程-附带代码展示 的相关文章

  • Qt Creator 2.8.1 Qt 5.1.1 Qt Designer Linux 显示新窗体

    我是 Qt 的初学者 所以希望这是一个容易回答的问题 我有相当多的 C 经验 这部分不是问题 我的应用程序的目的是进行代码生成 最初是为类制作头文件和实现文件 我非常喜欢 Code Blocks 上的类向导 但我认为我可以做更多的事情 我有
  • Qt:删除富文本

    对于明文有QFontMetrics elideText https doc qt io qt 5 qfontmetrics html elidedText https doc qt io qt 5 qfontmetrics html eli
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • QChart 对大数据集无响应

    我的这段代码适用于高达 1000 的数据大小 现在我用 65536 个点对其进行了测试 series new QLineSeries QList
  • QML改变图像颜色

    我搜索了如何对图像进行着色 格式为 svg 或 png 我尝试用一 个填充图像的矩形覆盖我的图像 但由于我的图像不是矩形 它会给整个矩形着色 而不仅仅是图像 可以用qml改变图像颜色吗 或者 是否可以使用 QPixmap 更改 qt 使用
  • QObject多重继承

    我正在尝试在 C Qt 类中使用 mix 来提供一大堆具有通用接口的小部件 该接口是以这样的方式定义的 如果它被定义为其他小部件类的基类 那么小部件本身将具有这些信号 class SignalInterface public QObject
  • 从 Qt 更改屏幕分辨率?

    我想更改屏幕分辨率 然后使用一个 ActiveX 控件 Flash 播放器 进入全屏 显然 仅适用于 Windows 的解决方案就可以了 有 Qt api 吗 还是我需要深入研究 winapi 如果是这样 我该在哪里查找 关键字 谢谢您的帮
  • QFileDialog 作为 TableView 的编辑器:如何获取结果?

    我正在使用一个QFileDialog作为某些专栏的编辑QTableView 这基本上有效 对一些焦点问题取模 请参阅here https stackoverflow com questions 22854242 qfiledialog as
  • 如何重写(重新实现)QFileSystemModel 中的成员函数

    我已经为此苦苦挣扎了一段时间 Qt s QFileSystemModel由于图标获取算法非常糟糕 在获取数百个文件时速度非常慢 我想完全禁用图标 它们被提取到QFileSystemModel data方法不是虚拟的 QFileSystemM
  • 无法将 [未定义] 分配给 QColor

    我正在使用 Qt 5 11 构建 运行代码 代码中有QML风格如下 Button style delegate Component id enabledButtonStyle ButtonStyle padding top 0 paddin
  • C++ QT libXL 错误:“启动期间程序退出,代码为 0xc0000135”

    我正在尝试编写一个使用 libXL 的 QT 应用程序 但是当我尝试编译时 我收到一个弹出框 显示 During Startup program exited with code 0xc0000135 我已经准确地找出了哪一行导致了问题 它
  • 如何使用bind将成员函数作为函数指针传递?

    我试图将成员函数作为函数指针传递 这样我就不需要依赖单例或全局函数来处理 Qt 5 中的 Qt 消息 据我所知 我的 std function 是正确的类型 它具有正确的签名 并且绑定应该允许我插入隐式this指针 本质上是将成员函数传递为
  • 构建qt程序时未定义的符号:找不到qt_version_tag

    我正在学习Qt5 6 我正在使用 Ubuntu 14 4 当我链接我的程序时 出现以下错误 undefined reference to qt version tag 在 CMakeLists txt 中 link libraries Qt
  • Qt 和 MOC 的困境与简单的制作

    我想这更像是一个 GNU Make 问题 而不是 Qt 和 moc 但这里是 我有一个包含多个目录Q OBJECTS 我有一些简单的代码 它收集所有这些 例如 MOCS shell grep l Q OBJECT HEADERS Assum
  • Qt - QProcess 不工作

    我尝试启动 Internet Explorer 所以我使用下面的代码 QProcess process new QProcess this QString temp C Program Files Internet Explorer iex
  • Qt QML MenuItem iconSource不显示

    我有一个非常简单的设置只是为了说明问题 import QtQuick Controls 1 4 import QtQuick Window 2 2 ApplicationWindow visible true width 640 heigh
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • QWebView等待加载

    bool MainWindow waitForLoad QWebView view QEventLoop loopLoad QTimer timer QObject connect view SIGNAL loadFinished bool
  • 如何使用样式表删除 QWizard 中的水平线?

    我正在研究一个样式表QWizard我想删除按钮上方的水平线 我已经发布了一个最小的例子here https stackoverflow com q 52538669 8570451 这个问题是由scopchanov从最小的例子中解决的 但是
  • 使用样式表时的 QTabWidget tabPosition

    我目前正在使用样式表来设计应用程序的主题 这是我用于 QTabWidget 的样式表 QTabBar et QTabWidget QTabBar tab background qlineargradient spread pad x1 0

随机推荐

  • Python深度学习篇一《什么是深度学习》

    在过去的几年里 人工智能 AI 一直是媒体大肆炒作的热点话题 机器学习 深度学习 和人工智能都出现在不计其数的文章中 而这些文章通常都发表于非技术出版物 我们的未来被描绘成拥有智能聊天机器人 自动驾驶汽车和虚拟助手 这一未来有时被渲染成可怕
  • Linux怎么使用U盘

    方案一 Linux不像Windows一样 接上新硬件后可以自动识别 在Linux下无法自动识别新硬件的 需要手动去识别 USB移动存储设备通常被识别为sda1 具体可以通过fdisk l命令查询 在使用U盘前 我们先要为外挂点新建一个子目录
  • 《动手学深度学习 Pytorch版》 6.5 汇聚层

    import torch from torch import nn from d2l import torch as d2l 6 5 1 最大汇聚和平均汇聚 汇聚层和卷积层类似 区别在于汇聚层不带包含参数 汇聚操作是确定性的 通常计算汇聚窗
  • [Unity踩坑记录] 从屏幕坐标系转换到世界坐标系

    问题描述 调试需要 想从摄像机发出一条射向鼠标指向位置的射线 于是写了如下代码 void Update Vector3 mouseScreenPos Input mousePosition Vector3 mouseWorldPos Cam
  • JS力扣刷题26. 删除有序数组中的重复项

    var removeDuplicates function nums len表示nums修改后得长度 let len nums length for let i 0 i lt len 1 i if nums i nums i 1 for l
  • Android开发精典案例60个

    实例简介 Android开发精典案例60个 文件 url80 ctfile com f 25127180 740794786 4b13cf p 551685 访问密码 551685 核心代码 2 1 Activity生命周期 3 1 But
  • 区块链结合物联网可研究方向

    文献来源 H Dai Z Zheng and Y Zhang Blockchain for Internet of Things A Survey in IEEE Internet of Things Journal vol 6 no 5
  • js怎么实现数组里的数据相加_JS数组求和的常用方法总结【5种方法】

    本文实例总结了JS数组求和的常用方法 分享给大家供大家参考 具体如下 题目描述 计算给定数组 arr 中所有元素的总和 输入描述 数组中的元素均为 Number 类型 输入例子 sum 1 2 3 4 输出例子 10 方法1 不考虑算法复杂
  • Powershell如何查询目录所有文件和文件夹的名称

    Powershell如何查询目录所有文件和文件夹的名称 获取文件名称 修改时间等 Get ChildItem Name设置可仅获取文件名称 Get ChildItem Name 输入 Get ChildItem 如图 输入 Get Chil
  • hdu 1007 Quoit Design

    Quoit Design Time Limit 10000 5000 MS Java Others Memory Limit 65536 32768 K Java Others Total Submission s 10498 Accept
  • MFC 菜单操作

    1 菜单是窗口框架的组成部分 如果我们要导入自定义的菜单 可以通过以下语句实现 在CMainFrame OnCreate的函数中添加如下代码段 SetMenu NULL 将原本的菜单项去除 CMenu menu 新定义一个菜单对象 menu
  • 计算机网络 --- DNS协议

    计算机网络 DNS协议 什么是DNS DNS工作原理 Overview Three Classes of DNS servers 1 Root servers 2 top level domain DNS servers 3 authori
  • Java学习(java基础)-韩顺平老师

    一 简单介绍 1 jdk jre 2 Java代码规范 a 类 方法的注释 要以javadoc的方式来写 author 楠小弟 version 1 0 public class Hello public static void main S
  • JDBC中典型的五种查询方式

    第一种查询方式 返回一个ArrayList集合 集合里面的数据类型只能为Empinfo类类型 public ArrayList
  • YOLOV5代码general.py文件解读

    YOLOV5源码的下载 git clone https github com ultralytics yolov5 git YOLOV5代码general py文件解读 import glob import logging import o
  • 深入浅出BP神经网络算法的原理

    相信每位刚接触神经网络的时候都会先碰到BP算法的问题 如何形象快速地理解BP神经网络就是我们学习的高级乐趣了 画外音 乐趣 你在跟我谈乐趣 本篇博文就是要简单粗暴地帮助各位童鞋快速入门采取BP算法的神经网络 BP神经网络是怎样的一种定义 看
  • vue项目实战(一)

    第一步 找到你想要存放项目的文件夹 输入cmd 就会弹出小黑窗 然后输入vue create 项目名 创建项目 前提安装好node js和搭建 vue 环境 打开终端 创建项目 按上下键进行选择 做一些配置 这次选择自定义 也就是最后一个
  • Java_得到GET和POST请求URL和参数列表

    一 获取URL getRequestURL 二 获取参数列表 1 getQueryString 只适用于GET 比如客户端发送http localhost testServlet a b c d e f 通过request getQuery
  • 计算机基础内容——网络基础

    网络基础 设备是如何上网的 网卡 有线 无线 内置天线 网线接口RJ45 usb转RJ45 交换机 路由器 外置天线 天线棒 光猫 宽带运营商 不同的宽带运营商之间是互通的 路由器发出的wifi信号 2 4GHz wifi 5 0GHz w
  • Qt的Tcp服务器多线程编程-附带代码展示

    Qt的Tcp服务器多线程编程 附带代码展示 该程序主要实现tcp服务器如何使用多线程的方式来连接多个客户端 此文章没有实现客户端的多线程编程 创建子线程时需要注意的点 1 子线程与主线程之间交互数据时 应采用信号槽的方式 2 子线程中实例化