QT + Tcp客户端,服务器(支持多客户端)

avatar
作者
筋斗云
阅读量:0

环境

Qt 5.4.2

功能

QT Tcp 服务器,多客户端通信

服务器源码

在这里插入图片描述

  1. TcpServerApp.pro
    QT += network

  2. mainwindow

mainwindow.h

#include "tcpserver.h"  class MainWindow : public QMainWindow {     Q_OBJECT public:     explicit MainWindow(QWidget *parent = 0);     ~MainWindow(); private:     Ui::MainWindow *ui; private:      QTreeWidgetItem *pServerItem;      QTreeWidgetItem *pClientItem;      QStandardItemModel* pClientModel;      TcpServer  tcpServer; private:     void InitTreeView();     void InitServerCfg();     void InitClientCfg(); private slots:     void slot_incomingConnect(QString socketID);     void slot_readMessage(QString socketId,QString message);     void slot_disconnected(QString socketId);     void slot_itemDoubleClicked(QTreeWidgetItem *item, int column);     void slot_curStateChanged(QString identify,int state);     void on_pushButton_Start_clicked();     void on_pushButton_Close_clicked();     void on_pushButton_Send_clicked();     void on_pushButton_SendAll_clicked();     void on_pushButton_CloseAll_clicked(); };  class MyCheckBox : public QCheckBox {     Q_OBJECT public:     explicit MyCheckBox(){}     ~MyCheckBox(){} public:     void SetIdentify(QString identify) { sIdentify = identify;      connect(this,SIGNAL(stateChanged(int)),this,SLOT(slot_stateChanged(int)));} signals:     void curStateChanged(QString identify,int state); private slots:     void slot_stateChanged(int state){emit curStateChanged(sIdentify,state);} private:     QString  sIdentify; }; #endif // MAINWINDOW_H 

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :     QMainWindow(parent),     ui(new Ui::MainWindow) {     ui->setupUi(this);     InitTreeView();     InitServerCfg();     InitClientCfg(); }  void MainWindow::InitTreeView() {     ui->treeWidget->setColumnCount(1);     ui->treeWidget->setHeaderLabel(tr("TCP 服务器"));     pServerItem = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("服务器")));// 添加QTreeWidget主节点;     pClientItem = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("客户端")));     QTreeWidgetItem *pServerItem_1 = new QTreeWidgetItem(pServerItem,QStringList(QString("配置管理")));     QTreeWidgetItem *pClientItem_1 = new QTreeWidgetItem(pClientItem,QStringList(QString("配置管理")));     connect(ui->treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(slot_itemDoubleClicked(QTreeWidgetItem*,int)));     ui->treeWidget->setCurrentItem(pServerItem_1);     ui->treeWidget->expandAll();     ui->stackedWidget->setCurrentIndex(0); }  void MainWindow::InitServerCfg() {     connect(&tcpServer,SIGNAL(incomingConnect(QString)),SLOT(slot_incomingConnect(QString)));     connect(&tcpServer,SIGNAL(readMessage(QString,QString)),SLOT(slot_readMessage(QString,QString)));     connect(&tcpServer,SIGNAL(disconnected(QString)),SLOT(slot_disconnected(QString)));     ui->pushButton_Start->setEnabled(true);     ui->pushButton_Close->setEnabled(false); }  void MainWindow::InitClientCfg() {     pClientModel = new QStandardItemModel();     ui->tableView_RecvAll->verticalHeader()->setVisible(false);     ui->tableView_RecvAll->horizontalHeader()->setVisible(false);     ui->tableView_RecvAll->setModel(pClientModel);     pClientModel->setColumnCount(2);                                     ui->tableView_RecvAll->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);     ui->tableView_RecvAll->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);     ui->tableView_RecvAll->setColumnWidth(0, 80);     ui->tableView_RecvAll->setEditTriggers(QAbstractItemView::NoEditTriggers);     MyCheckBox *pAllCheck = new MyCheckBox();     pAllCheck->setText("全选");     pAllCheck->SetIdentify("All");     connect(pAllCheck,SIGNAL(curStateChanged(QString,int)),this,SLOT(slot_curStateChanged(QString,int)));     pClientModel->setRowCount(1);     ui->tableView_RecvAll->setRowHeight(0,40);     ui->tableView_RecvAll->setIndexWidget(pClientModel->index(0,0),pAllCheck);     pClientModel->setItem(0, 1, new QStandardItem("客户端" ) );     ui->pushButton_SendAll->setEnabled(false);     ui->pushButton_CloseAll->setEnabled(false); } void MainWindow::slot_incomingConnect(QString socketID) {     QTreeWidgetItem *pClientItem_N = new QTreeWidgetItem(pClientItem,QStringList(socketID));     pClientModel->setRowCount(pClientModel->rowCount()+1);     MyCheckBox *pOneCheck = new MyCheckBox();     pOneCheck->SetIdentify(socketID);     connect(pOneCheck,SIGNAL(curStateChanged(QString,int)),this,SLOT(slot_curStateChanged(QString,int)));     ui->tableView_RecvAll->setIndexWidget(pClientModel->index(pClientModel->rowCount()-1,0),pOneCheck);     pClientModel->setItem(pClientModel->rowCount()-1, 1, new QStandardItem(socketID) );     ui->tableView_RecvAll->setRowHeight(pClientModel->rowCount()-1,40); } void MainWindow::slot_readMessage(QString socketId, QString message) {     QString sSocketID =  "客户端[" + socketId + "]";     if(ui->label_Info->text() == sSocketID)     {         ui->textEdit_Recv->setText(message);     } } void MainWindow::slot_disconnected(QString socketId) {     for(int i=0; i<pClientItem->childCount(); i++)     {         if(pClientItem->child(i)->text(0) == socketId)         {             pClientItem->removeChild(pClientItem->child(i));             break;         }     }          for(int i=1; i<pClientModel->rowCount(); i++)     {         if(socketId == pClientModel->item(i,1)->text())         {             pClientModel->removeRow(i);         }     }     ui->treeWidget->setCurrentItem(pClientItem->child(0));     ui->stackedWidget->setCurrentIndex(1); }  void MainWindow::slot_itemDoubleClicked(QTreeWidgetItem *item, int column) {     if(NULL == item->parent()) { return; }     if(item->parent() == pServerItem)     {         ui->stackedWidget->setCurrentIndex(0);         return;     }     if("配置管理" == item->text(0))     {        ui->stackedWidget->setCurrentIndex(1);        return;     }     QString sTitleMsg  = "客户端[" + item->text(0) + "]";     ui->label_Info->setText(sTitleMsg);     ui->stackedWidget->setCurrentIndex(2);     ui->textEdit_Send->clear();     ui->textEdit_Recv->setText(tcpServer.GetRecvMesg(item->text(0))); }  void MainWindow::slot_curStateChanged(QString identify, int state) {    if("All" != identify) { return; }    MyCheckBox *pCheckBox;        for(int i=1; i<pClientModel->rowCount(); i++)    {        pCheckBox = (MyCheckBox*)ui->tableView_RecvAll->indexWidget(pClientModel->index(i,0));        switch(state)        {         case 0: pCheckBox->setChecked(false); break;         case 2: pCheckBox->setChecked(true);  break;         default:break;        }    } }  void MainWindow::on_pushButton_Start_clicked() {     ui->label_ServerSts->setText("");     if(!tcpServer.listen(QHostAddress::Any,ui->spinBox_Port->value()))     {         ui->label_ServerSts->setText("Failed to bind port !");         return;     }      ui->pushButton_Start->setEnabled(false);     ui->pushButton_Close->setEnabled(true);     ui->pushButton_SendAll->setEnabled(true);     ui->pushButton_CloseAll->setEnabled(true); }  void MainWindow::on_pushButton_Close_clicked() {     tcpServer.close();     tcpServer.ClearClientAll();     ui->pushButton_Start->setEnabled(true);     ui->pushButton_Close->setEnabled(false);     ui->pushButton_SendAll->setEnabled(false);     ui->pushButton_CloseAll->setEnabled(false); } void MainWindow::on_pushButton_Send_clicked() {     QString sSocketID =  ui->label_Info->text();     sSocketID = sSocketID.mid(sSocketID.indexOf("[")+1,sSocketID.lastIndexOf("]") - sSocketID.indexOf("[")-1);     tcpServer.SendMessage(sSocketID,ui->textEdit_Send->toPlainText());     ui->textEdit_Send->clear();     ui->textEdit_Recv->setText(tcpServer.GetRecvMesg(sSocketID)); }  void MainWindow::on_pushButton_SendAll_clicked() {     if("" == ui->textEdit_RecvAll->toPlainText()) { return; }     MyCheckBox *pCheckBox;     for(int i=1; i<pClientModel->rowCount(); i++)     {         pCheckBox = (MyCheckBox*)ui->tableView_RecvAll->indexWidget(pClientModel->index(i,0));         switch(pCheckBox->checkState())         {           case Qt::Checked :           {             tcpServer.SendMessage(pClientModel->item(i,1)->text(),ui->textEdit_RecvAll->toPlainText());           }break;           default:break;         }     } }  void MainWindow::on_pushButton_CloseAll_clicked() {     MyCheckBox *pCheckBox;     for(int i=1; i<pClientModel->rowCount(); i++)     {         pCheckBox = (MyCheckBox*)ui->tableView_RecvAll->indexWidget(pClientModel->index(i,0));         switch(pCheckBox->checkState())         {           case Qt::Checked :           {             tcpServer.CloseSocket(pClientModel->item(i,1)->text());           }break;           default:break;         }     } }  
  1. tcpserver
    tcpserver.h
#include "tcpsocket.h"  class TcpServer : public QTcpServer {     Q_OBJECT public:     TcpServer();     ~TcpServer();     void ClearClientAll();     void SendMessage(QString socketId,QString message);     void CloseSocket(QString socketId);     QString GetRecvMesg(QString socketId); protected:     void incomingConnection(int socketId); private:     QMap<QString,TcpSocket *> clientArray; private slots:     void slot_readMsg(QString socketId,QString message);     void slot_disconnect(QString socketId); signals:     void incomingConnect(QString socketId);     void readMessage(QString socketId,QString message);     void disconnected(QString socketId); }; #endif // TCPSERVER_H  

tcpserver.cpp

#include "tcpserver.h"  void TcpServer::ClearClientAll() {     for (QString key : clientArray.keys())     {         clientArray[key]->close();     }     clientArray.clear(); }  void TcpServer::SendMessage(QString socketId, QString message) {     if(clientArray.contains(socketId))     {         clientArray[socketId]->SendMessage(message);     } } void TcpServer::CloseSocket(QString socketId) {     if(clientArray.contains(socketId))     {         clientArray[socketId]->close();     } }  QString TcpServer::GetRecvMesg(QString socketId) {     if(clientArray.contains(socketId))     {         return clientArray[socketId]->GetRecvMesg();     } }  void TcpServer::incomingConnection(int socketId) {    TcpSocket *pTcpSocket = new TcpSocket();    pTcpSocket->setSocketDescriptor(socketId);    QString sClientInfo =  "ID:"+QString::number(socketId) + ",IP:" + pTcpSocket->peerAddress().toString() + ":"+ QString::number(pTcpSocket->peerPort());    pTcpSocket->SetSocketID(sClientInfo);    clientArray.insert(sClientInfo,pTcpSocket);    connect(pTcpSocket,SIGNAL(readMsg(QString,QString)),SLOT(slot_readMsg(QString,QString)));    connect(pTcpSocket,SIGNAL(disconnect(QString)),SLOT(slot_disconnect(QString)));    emit incomingConnect(sClientInfo); }  void TcpServer::slot_readMsg(QString socketId, QString message) {     emit readMessage(socketId,message); }  void TcpServer::slot_disconnect(QString socketId) {    clientArray[socketId]->close();    clientArray.remove(socketId);    emit disconnected(socketId); }  
  1. tcpsocket
    tcpsocket.h
class TcpSocket : public QTcpSocket {     Q_OBJECT public:     TcpSocket();     ~TcpSocket();     void SetSocketID(QString socketID);     void SendMessage(QString message);     QString GetRecvMesg(); private:     QString sSocketID;     QStringList sRecvMesg; private slots:     void slot_readyRead();     void slot_disconnected(); signals:     void readMsg(QString socketId,QString message);     void disconnect(QString socketId); };  #endif // TCPSOCKET_H  

tcpsocket.cpp

TcpSocket::TcpSocket() {     sSocketID = "";     sRecvMesg.clear();     connect(this,SIGNAL(readyRead()),this,SLOT(slot_readyRead()));     connect(this,SIGNAL(disconnected()),this,SLOT(slot_disconnected())); }  void TcpSocket::SetSocketID(QString socketID) {     sSocketID = socketID; }  void TcpSocket::SendMessage(QString message) {     this->write(message.toLatin1());      if(sRecvMesg.count() > 1024) { sRecvMesg.removeAt(0);}      QString sReadMsg = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + ": S -> " + message;     sRecvMesg.append(sReadMsg); }  QString TcpSocket::GetRecvMesg() {     return sRecvMesg.join("\n"); }  void TcpSocket::slot_readyRead() {     if(sRecvMesg.count() > 1024) { sRecvMesg.removeAt(0);}     QString sReadMsg = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + ": R -> " + QString(this->readAll());     sRecvMesg.append(sReadMsg);     emit readMsg(sSocketID,sRecvMesg.join("\n")); } void TcpSocket::slot_disconnected() {     emit disconnect(sSocketID); } 

客户端源码

在这里插入图片描述

  1. TcpClientApp.pro
    QT += network

  2. mainwindow
    mainwindow.h

class MainWindow : public QMainWindow {     Q_OBJECT public:     explicit MainWindow(QWidget *parent = 0);     ~MainWindow(); private:     Ui::MainWindow *ui;  private slots:     void slot_connected();     void slot_readyRead();     void slot_disconnected();     void on_pushButton_Connect_clicked();     void on_pushButton_Send_clicked();     void on_pushButton_Close_clicked(); private:     QTcpSocket tcpSocket; }; #endif // MAINWINDOW_H  

mainwindow.cpp

#include "mainwindow.h" #include "ui_mainwindow.h"  MainWindow::MainWindow(QWidget *parent) :     QMainWindow(parent),     ui(new Ui::MainWindow) {     ui->setupUi(this);      connect(&tcpSocket,SIGNAL(connected()),this,SLOT(slot_connected()));     connect(&tcpSocket,SIGNAL(readyRead()),this,SLOT(slot_readyRead()));     connect(&tcpSocket,SIGNAL(disconnected()),this,SLOT(slot_disconnected()));     ui->label_sts->setText("disconnected");     ui->pushButton_Connect->setEnabled(true);     ui->pushButton_Send->setEnabled(false);     ui->pushButton_Close->setEnabled(false); }  void MainWindow::slot_connected() {     ui->label_sts->setText("connected");     ui->pushButton_Connect->setEnabled(false);     ui->pushButton_Send->setEnabled(true);     ui->pushButton_Close->setEnabled(true); }  void MainWindow::slot_readyRead() {     QString sMessage = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + ": R -> " + QString(tcpSocket.readAll());     if(ui->textEdit_Recv->document()->lineCount() > 1024)     {         ui->textEdit_Recv->clear();     }     ui->textEdit_Recv->append(sMessage); }  void MainWindow::slot_disconnected() {     ui->label_sts->setText("disconnected");     ui->pushButton_Connect->setEnabled(true);     ui->pushButton_Send->setEnabled(false);     ui->pushButton_Close->setEnabled(false); } void MainWindow::on_pushButton_Connect_clicked() {     tcpSocket.connectToHost(QHostAddress(ui->lineEdit_IP->text()),ui->spinBox_Port->value()); } void MainWindow::on_pushButton_Send_clicked() {     tcpSocket.write(ui->textEdit_Send->toPlainText().toLatin1());     if(ui->textEdit_Recv->document()->lineCount() > 1024)     {         ui->textEdit_Recv->clear();     }     QString sMessage = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + ": S -> " + ui->textEdit_Send->toPlainText();     ui->textEdit_Recv->append(sMessage);     ui->textEdit_Send->clear(); }  void MainWindow::on_pushButton_Close_clicked() {     tcpSocket.close(); }  

运行结果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!