当前位置:   article > 正文

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

qt tcp多线程

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

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

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();
    });

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

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;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/187339
推荐阅读
相关标签
  

闽ICP备14008679号