int main(int argc, char *argv[]){ QApplication a(argc, argv); Widget w; w.show(); return a.exec();}主线程Widget.h文件#ifndef WIDGET_H#define WIDGET_H#include
当前位置:   article > 正文

Qt搭建多线程服务器_qwebserver多线程

qwebserver多线程

main.cpp 文件

  1. #include "Widget.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. Widget w;
  7. w.show();
  8. return a.exec();
  9. }

主线程

Widget.h文件

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QListWidget>
  5. #include <QPushButton>
  6. #include <QLabel>
  7. #include <QThread>
  8. #include "Work.h"
  9. class Widget : public QWidget
  10. {
  11. Q_OBJECT
  12. public:
  13. Widget(QWidget *parent = nullptr);
  14. ~Widget();
  15. private:
  16. void init();
  17. void rcvListenData(QString strData, QString strBtnData);
  18. void rcvConnectData(QString strData, QString strBtnData);
  19. void rcvMsg(QString strData, QString strBtnData);
  20. private:
  21. QListWidget* m_pList;
  22. QLabel* m_pLbListen;
  23. QPushButton* m_pBtn;
  24. Work* m_pWork;
  25. QThread* m_pThread;
  26. signals:
  27. void operate(bool bClose = false);
  28. public slots:
  29. void onRcvData(Work::MsgTag tag, QString strData, QString strBtnData = "close listen");
  30. };
  31. #endif // WIDGET_H

Widget.cpp文件

  1. #include "Widget.h"
  2. #include <QPluginLoader>
  3. #include <QDebug>
  4. #include <QVBoxLayout>
  5. #include <QHBoxLayout>
  6. #include <QDesktopWidget>
  7. Widget::Widget(QWidget *parent)
  8. : QWidget(parent)
  9. {
  10. init();
  11. m_pThread = new QThread(this);
  12. m_pWork = new Work();
  13. m_pThread->start();
  14. connect(m_pThread, &QThread::finished, m_pWork, &Work::deleteLater);
  15. connect(this, &Widget::operate, m_pWork, &Work::OnWork);
  16. connect(m_pWork, &Work::sigToMainThread, this, &Widget::onRcvData);
  17. m_pWork->moveToThread(m_pThread);
  18. this->setWindowTitle(tr("server"));
  19. }
  20. Widget::~Widget()
  21. {
  22. m_pThread->quit();
  23. m_pThread->wait();
  24. }
  25. void Widget::init()
  26. {
  27. QDesktopWidget destWidget;
  28. int nHight = destWidget.geometry().height();
  29. int nWidth = destWidget.geometry().width();
  30. this->resize(nWidth/2, nHight/2);
  31. m_pList = new QListWidget;
  32. m_pBtn = new QPushButton(tr("start listen"));
  33. m_pLbListen = new QLabel(tr(""));
  34. connect(m_pBtn, &QPushButton::clicked, [&]{
  35. if(m_pBtn->text() == tr("start listen"))
  36. emit operate(false);
  37. else
  38. emit operate(true);
  39. });
  40. QHBoxLayout* pHBtnLayout = new QHBoxLayout;
  41. pHBtnLayout->addWidget(m_pLbListen);
  42. pHBtnLayout->addWidget(m_pBtn);
  43. QHBoxLayout* pHListLayout = new QHBoxLayout;
  44. pHListLayout->addWidget(m_pList);
  45. QVBoxLayout* pVMainLayout = new QVBoxLayout;
  46. pVMainLayout->addLayout(pHListLayout);
  47. pVMainLayout->addLayout(pHBtnLayout);
  48. this->setLayout(pVMainLayout);
  49. }
  50. void Widget::rcvListenData(QString strData, QString strBtnData)
  51. {
  52. m_pBtn->setText(strBtnData);
  53. m_pLbListen->setText(strData);
  54. }
  55. void Widget::rcvConnectData(QString strData, QString strBtnData)
  56. {
  57. m_pBtn->setText(strBtnData);
  58. QListWidgetItem* pItem = new QListWidgetItem(strData);
  59. m_pList->addItem(pItem);
  60. }
  61. void Widget::rcvMsg(QString strData, QString strBtnData)
  62. {
  63. m_pBtn->setText(strBtnData);
  64. QListWidgetItem* pItem = new QListWidgetItem(strData);
  65. m_pList->addItem(pItem);
  66. }
  67. void Widget::onRcvData(Work::MsgTag tag, QString strData, QString strBtnData)
  68. {
  69. qDebug() << strBtnData;
  70. switch(tag)
  71. {
  72. case Work::ID_Listen:
  73. rcvListenData(strData,strBtnData);
  74. break;
  75. case Work::ID_Conect:
  76. rcvConnectData(strData, strBtnData);
  77. break;
  78. case Work::ID_Msg:
  79. rcvMsg(strData, strBtnData);
  80. break;
  81. default:
  82. break;
  83. }
  84. }

工作线程

Work.h文件

  1. #ifndef WORK_H
  2. #define WORK_H
  3. #include <QObject>
  4. #include <QWidget>
  5. //监听套接字
  6. #include <QTcpServer>
  7. class Work : public QObject
  8. {
  9. Q_OBJECT
  10. public:
  11. enum MsgTag
  12. {
  13. ID_Listen, //监听
  14. ID_Conect, //连接
  15. ID_Msg //信息
  16. };
  17. Q_ENUM(MsgTag)
  18. explicit Work(QObject *parent = nullptr);
  19. private:
  20. void serverConnect();
  21. void serverDisconnect();
  22. private:
  23. QTcpServer* m_pTcpServer;
  24. QSet<QTcpSocket*> m_SetSock;
  25. signals:
  26. void sigToMainThread(Work::MsgTag tag, QString strData, QString strBtn = "close Listen");
  27. public slots:
  28. void OnWork(bool bClose);
  29. void onRecvData(QTcpSocket* pSocket);
  30. void onDisconnect(QTcpSocket *pSocket);
  31. };
  32. #endif // WORK_H

Work.cpp

  1. #include "Work.h"
  2. #include <QTextCodec>
  3. #include <QDebug>
  4. #include <QTcpSocket>
  5. Work::Work(QObject *parent) : QObject(parent)
  6. {
  7. qRegisterMetaType<MsgTag>();
  8. m_pTcpServer = new QTcpServer(this);
  9. connect(m_pTcpServer, &QTcpServer::newConnection, [=]{
  10. QTcpSocket* pSocket = m_pTcpServer->nextPendingConnection();
  11. //获取客户端的Ip和端口
  12. qint32 ip = pSocket->peerAddress().toIPv4Address();
  13. QString strIP = QHostAddress(ip).toString();
  14. QString strPort = QString::number(pSocket->peerPort());
  15. m_SetSock.insert(pSocket);
  16. qDebug() << m_SetSock.count();
  17. QString connectText = "IP:" + strIP + "," + "Port:" + strPort + "connect server !";
  18. emit sigToMainThread(ID_Conect, connectText);
  19. connect(pSocket, &QTcpSocket::readyRead, [=]{
  20. QByteArray byteArry;
  21. byteArry = pSocket->readAll();
  22. qint32 ip = pSocket->peerAddress().toIPv4Address();
  23. QString strIP = QHostAddress(ip).toString();
  24. uint port = pSocket->peerPort();
  25. //防止中文乱码
  26. QTextCodec *tc = QTextCodec::codecForName("GBK");
  27. QString strTotalData = strIP + QString::number(port) + ":" + tc->toUnicode(byteArry);
  28. emit sigToMainThread(ID_Msg, strTotalData);
  29. });
  30. connect(pSocket, &QTcpSocket::disconnected, this, [=]{
  31. qint32 ip = pSocket->peerAddress().toIPv4Address();
  32. QString strIP = QHostAddress(ip).toString();
  33. QString strTotal = strIP + ":" + "disconnect !";
  34. emit sigToMainThread(ID_Msg, strTotal);
  35. });
  36. });
  37. }
  38. void Work::OnWork(bool bClose)
  39. {
  40. if(!bClose)
  41. serverConnect();
  42. else
  43. serverDisconnect();
  44. }
  45. void Work::onRecvData(QTcpSocket *pSocket)
  46. {
  47. QByteArray byteArry;
  48. byteArry = pSocket->readAll();
  49. qint32 ip = pSocket->peerAddress().toIPv4Address();
  50. QString strIP = QHostAddress(ip).toString();
  51. uint port = pSocket->peerPort();
  52. //防止中文乱码
  53. QTextCodec *tc = QTextCodec::codecForName("GBK");
  54. QString strTotalData = strIP + QString::number(port) + ":" + tc->toUnicode(byteArry);
  55. emit sigToMainThread(ID_Msg, strTotalData);
  56. }
  57. void Work::onDisconnect(QTcpSocket *pSocket)
  58. {
  59. qint32 ip = pSocket->peerAddress().toIPv4Address();
  60. QString strIP = QHostAddress(ip).toString();
  61. QString strTotal = strIP + ":" + "disconnect !";
  62. emit sigToMainThread(ID_Msg, strTotal);
  63. }
  64. void Work::serverConnect()
  65. {
  66. if(! m_pTcpServer->listen(QHostAddress::Any, 666))
  67. emit sigToMainThread(ID_Listen, "listen failed", "start Listen");
  68. else
  69. emit sigToMainThread(ID_Listen, "listening...");
  70. }
  71. void Work::serverDisconnect()
  72. {
  73. m_pTcpServer->close();
  74. if(! m_pTcpServer->isListening())
  75. emit sigToMainThread(ID_Listen, "server disconnect !", "start listen");
  76. else
  77. emit sigToMainThread(ID_Listen, "server disconnect fauiled!");
  78. }

下面补上客户端代码:

main.cpp文件

  1. #include "Widget.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. Widget w;
  7. w.show();
  8. return a.exec();
  9. }

Widget.h文件

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QTcpSocket>
  5. #include <QLabel>
  6. #include <QPushButton>
  7. #include <QLineEdit>
  8. class Widget : public QWidget
  9. {
  10. Q_OBJECT
  11. public:
  12. Widget(QWidget *parent = nullptr);
  13. ~Widget();
  14. private:
  15. void init();
  16. private:
  17. QTcpSocket* m_pTcpSocket;
  18. QPushButton* m_pBtnConnect;
  19. QLabel* m_pLbIP;
  20. QLabel* m_pLbPort;
  21. QLineEdit* m_pLineIP;
  22. QLineEdit* m_pLinePort;
  23. bool m_bOnLine;
  24. public slots:
  25. void onReadData();
  26. void onSocketError(QAbstractSocket:: SocketError nError);
  27. void onConnectClicked();
  28. void onConnected();
  29. void onDisConnected();
  30. };
  31. #endif // WIDGET_H

widget.cpp

  1. #include "Widget.h"
  2. #include <QHBoxLayout>
  3. #include <QVBoxLayout>
  4. #include <QDesktopWidget>
  5. #include <QTextCodec>
  6. Widget::Widget(QWidget *parent)
  7. : QWidget(parent)
  8. {
  9. QDesktopWidget* pWidget = new QDesktopWidget;
  10. int nWidth = pWidget->geometry().width();
  11. int nHight = pWidget->geometry().height();
  12. this->resize(nWidth/2, nHight/2);
  13. setWindowTitle("client");
  14. m_pTcpSocket = new QTcpSocket(this);
  15. m_bOnLine = false;
  16. init();
  17. connect(m_pTcpSocket, &QTcpSocket::connected, this, &Widget::onConnected);
  18. connect(m_pTcpSocket, &QTcpSocket::readyRead, this, &Widget::onReadData);
  19. connect(m_pTcpSocket, &QTcpSocket::disconnected, this, &Widget::onDisConnected);
  20. connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
  21. }
  22. Widget::~Widget()
  23. {
  24. }
  25. void Widget::init()
  26. {
  27. m_pLbIP = new QLabel(tr("IP:"));
  28. m_pLbPort = new QLabel(tr("Port:"));
  29. m_pLineIP = new QLineEdit;
  30. m_pLinePort = new QLineEdit;
  31. m_pBtnConnect = new QPushButton(tr("连接"));
  32. connect(m_pBtnConnect, &QPushButton::clicked, this, &Widget::onConnectClicked);
  33. QHBoxLayout* pHIpLayout = new QHBoxLayout;
  34. pHIpLayout->addWidget(m_pLbIP);
  35. pHIpLayout->addWidget(m_pLineIP);
  36. QHBoxLayout* pHPortLayout = new QHBoxLayout;
  37. pHPortLayout->addWidget(m_pLbPort);
  38. pHPortLayout->addWidget(m_pLinePort);
  39. QHBoxLayout* pHBtnLayout = new QHBoxLayout;
  40. pHBtnLayout->addStretch();
  41. pHBtnLayout->addWidget(m_pBtnConnect);
  42. QVBoxLayout* pVMainLayout = new QVBoxLayout;
  43. pVMainLayout->addLayout(pHIpLayout);
  44. pVMainLayout->addLayout(pHPortLayout);
  45. pVMainLayout->addLayout(pHBtnLayout);
  46. this->setLayout(pVMainLayout);
  47. }
  48. void Widget::onReadData()
  49. {
  50. if(m_pTcpSocket->bytesAvailable())
  51. {
  52. QByteArray buf = m_pTcpSocket->readAll();
  53. QTextCodec *tc = QTextCodec::codecForName("GBK");
  54. QString strTotalData =tc->toUnicode(buf);
  55. qDebug() << strTotalData;
  56. }
  57. }
  58. void Widget::onSocketError(QAbstractSocket::SocketError nError)
  59. {
  60. qDebug() << "Error ID:" + QString::number(nError);
  61. }
  62. void Widget::onConnectClicked()
  63. {
  64. if(! m_bOnLine)
  65. {
  66. QString strIp = m_pLineIP->text();
  67. QString strPort = m_pLinePort->text();
  68. m_pTcpSocket->connectToHost(strIp,strPort.toShort());
  69. }
  70. else
  71. {
  72. m_bOnLine = false;
  73. m_pTcpSocket->disconnectFromHost();
  74. m_pBtnConnect->setText("连接");
  75. }
  76. }
  77. void Widget::onConnected()
  78. {
  79. qDebug() << "连接服务器成功!";
  80. m_bOnLine = true;
  81. m_pBtnConnect->setText(tr("断开连接"));
  82. }
  83. void Widget::onDisConnected()
  84. {
  85. qDebug() << "已断开与服务器的连接!";
  86. m_bOnLine = false;
  87. m_pBtnConnect->setText(tr("连接"));
  88. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/187358
推荐阅读
相关标签