阅读量:0
环境
Qt 5.4.2
功能
QT Tcp 服务器,多客户端通信
服务器源码
TcpServerApp.pro
QT += networkmainwindow
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; } } }
- 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); }
- 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); }
客户端源码
TcpClientApp.pro
QT += networkmainwindow
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(); }