├── .gitignore ├── LICENSE ├── QNetworkAccessManagerReadHttp ├── QNetworkAccessManagerReadHttp.pro ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui ├── QTcpSocketExample ├── QTcpSocketExample.pro ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui ├── QUdpSocketExample ├── QUdpSocketExample.pro ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui ├── README.md └── SupportMulticlientsTcpserver ├── SupportMulticlientsTcpserver.pro ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── tcp_server.cpp ├── tcp_server.h ├── tcp_server_private.cpp └── tcp_server_private.h /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | moc_*.h 24 | qrc_*.cpp 25 | ui_*.h 26 | Makefile* 27 | *build-* 28 | 29 | # QtCreator 30 | 31 | *.autosave 32 | 33 | # QtCtreator Qml 34 | *.qmlproject.user 35 | *.qmlproject.user.* 36 | 37 | # QtCtreator CMake 38 | CMakeLists.txt.user* 39 | 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Techie Liang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /QNetworkAccessManagerReadHttp/QNetworkAccessManagerReadHttp.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-12-20T14:28:02 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += network 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QNetworkAccessManagerReadHttp 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which has been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | 26 | SOURCES += \ 27 | main.cpp \ 28 | mainwindow.cpp 29 | 30 | HEADERS += \ 31 | mainwindow.h 32 | 33 | FORMS += \ 34 | mainwindow.ui 35 | -------------------------------------------------------------------------------- /QNetworkAccessManagerReadHttp/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /QNetworkAccessManagerReadHttp/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | MainWindow::MainWindow(QWidget *parent) : 5 | QMainWindow(parent), 6 | ui(new Ui::MainWindow) { 7 | ui->setupUi(this); 8 | reply = Q_NULLPTR; 9 | } 10 | 11 | MainWindow::~MainWindow() { 12 | delete ui; 13 | } 14 | 15 | void MainWindow::Get(QUrl u) { 16 | QNetworkRequest request; 17 | url=u; 18 | request.setUrl(url); 19 | if(reply != Q_NULLPTR) {//更改reply指向位置钱一定要保证之前的定义了自动delete 20 | reply->deleteLater(); 21 | } 22 | reply = manager.get(request); 23 | qDebug() << "start get"; 24 | connect(reply, &QNetworkReply::finished, this, &MainWindow::finished); 25 | } 26 | 27 | void MainWindow::on_pushButton_clicked() { 28 | html_text = ""; 29 | Get(QUrl("http://www.sina.com/")); 30 | 31 | } 32 | 33 | void MainWindow::finished() { 34 | QByteArray bytes = reply->readAll(); 35 | const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); 36 | reply->deleteLater(); 37 | reply = Q_NULLPTR; 38 | if (!redirectionTarget.isNull()) {//如果网址跳转重新请求 39 | const QUrl redirectedUrl = url.resolved(redirectionTarget.toUrl()); 40 | qDebug()<<"redirectedUrl:"<textEdit->setPlainText(html_text); 48 | // QFile f("result.html");//写出文件 49 | // f.open(QFile::WriteOnly); 50 | // f.write(bytes); 51 | // f.close(); 52 | } 53 | -------------------------------------------------------------------------------- /QNetworkAccessManagerReadHttp/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | #include 4 | #include 5 | #include 6 | namespace Ui { 7 | class MainWindow; 8 | } 9 | 10 | class MainWindow : public QMainWindow { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit MainWindow(QWidget *parent = 0); 15 | ~MainWindow(); 16 | void Get(QUrl u); 17 | private slots: 18 | void on_pushButton_clicked(); 19 | void finished(); 20 | private: 21 | Ui::MainWindow *ui; 22 | QNetworkAccessManager manager; 23 | QUrl url; 24 | QNetworkReply *reply; 25 | QString html_text; 26 | }; 27 | 28 | #endif // MAINWINDOW_H 29 | -------------------------------------------------------------------------------- /QNetworkAccessManagerReadHttp/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | PushButton 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /QTcpSocketExample/QTcpSocketExample.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-12-20T13:43:10 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += network 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QTcpSocketExample 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which has been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | 26 | SOURCES += \ 27 | main.cpp \ 28 | mainwindow.cpp 29 | 30 | HEADERS += \ 31 | mainwindow.h 32 | 33 | FORMS += \ 34 | mainwindow.ui 35 | -------------------------------------------------------------------------------- /QTcpSocketExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /QTcpSocketExample/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | #include 5 | #include 6 | MainWindow::MainWindow(QWidget *parent) : 7 | QMainWindow(parent), 8 | ui(new Ui::MainWindow) { 9 | ui->setupUi(this); 10 | server = new QTcpServer(); 11 | connect(server, 12 | &QTcpServer::newConnection, 13 | this, 14 | &MainWindow::server_New_Connect);//监听 15 | if(!server->listen(QHostAddress::Any, 80100)) { 16 | qDebug()<errorString(); //错误信息 17 | } 18 | //客户端建立 19 | m_socket = new QTcpSocket; 20 | m_socket->connectToHost("127.0.0.1",80100,QTcpSocket::ReadWrite); 21 | if(!m_socket->waitForConnected()) { 22 | qDebug()<<"client connect error"; 23 | } 24 | m_socket->write("i'm in"); 25 | } 26 | 27 | MainWindow::~MainWindow() { 28 | delete ui; 29 | } 30 | 31 | void MainWindow::server_New_Connect() { 32 | //获取客户端连接 33 | m_server_socket = server->nextPendingConnection();//根据当前新连接创建一个QTepSocket 34 | //连接QTcpSocket的信号槽,以读取新数据 35 | QObject::connect(m_server_socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); 36 | //当断开连接时发出的信号 37 | // QObject::connect(socket_temp, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected); 38 | qDebug()<<"new clinet connect in"; 39 | } 40 | 41 | void MainWindow::socket_Read_Data(){ 42 | qDebug()<readAll(); 43 | } 44 | -------------------------------------------------------------------------------- /QTcpSocketExample/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | class QTcpSocket; 6 | class QTcpServer; 7 | namespace Ui { 8 | class MainWindow; 9 | } 10 | 11 | class MainWindow : public QMainWindow 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit MainWindow(QWidget *parent = 0); 17 | ~MainWindow(); 18 | private slots: 19 | void server_New_Connect(); 20 | void socket_Read_Data(); 21 | 22 | private: 23 | Ui::MainWindow *ui; 24 | QTcpSocket *m_socket,*m_server_socket; 25 | QTcpServer *server; 26 | }; 27 | 28 | #endif // MAINWINDOW_H 29 | -------------------------------------------------------------------------------- /QTcpSocketExample/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | MainWindow 3 | 4 | 5 | 6 | 0 7 | 0 8 | 400 9 | 300 10 | 11 | 12 | 13 | MainWindow 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /QUdpSocketExample/QUdpSocketExample.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-12-20T13:58:46 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += network 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QUdpSocketExample 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which has been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | 26 | SOURCES += \ 27 | main.cpp \ 28 | mainwindow.cpp 29 | 30 | HEADERS += \ 31 | mainwindow.h 32 | 33 | FORMS += \ 34 | mainwindow.ui 35 | -------------------------------------------------------------------------------- /QUdpSocketExample/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /QUdpSocketExample/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | MainWindow::MainWindow(QWidget *parent) : 8 | QMainWindow(parent), 9 | ui(new Ui::MainWindow) { 10 | ui->setupUi(this); 11 | QUdpSocket *m_server=new QUdpSocket; 12 | m_server->bind(8000); 13 | m_server->open(QUdpSocket::ReadWrite); 14 | connect(m_server, 15 | &QUdpSocket::readyRead, 16 | this, 17 | [=](){ 18 | while (m_server->hasPendingDatagrams()) { 19 | QByteArray datagram; 20 | QHostAddress address; 21 | quint16 port = 8000; 22 | datagram.resize(m_server->pendingDatagramSize()); 23 | m_server->readDatagram(datagram.data(), 24 | datagram.size(), 25 | &address, 26 | &port); 27 | qDebug()<<"server rev:"<writeDatagram("client in", QHostAddress::LocalHost, 8000); 32 | m_socket->waitForBytesWritten(); 33 | } 34 | 35 | MainWindow::~MainWindow() { 36 | delete ui; 37 | } 38 | -------------------------------------------------------------------------------- /QUdpSocketExample/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class MainWindow; 8 | } 9 | 10 | class MainWindow : public QMainWindow 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit MainWindow(QWidget *parent = 0); 16 | ~MainWindow(); 17 | 18 | private: 19 | Ui::MainWindow *ui; 20 | }; 21 | 22 | #endif // MAINWINDOW_H 23 | -------------------------------------------------------------------------------- /QUdpSocketExample/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | MainWindow 3 | 4 | 5 | 6 | 0 7 | 0 8 | 400 9 | 300 10 | 11 | 12 | 13 | MainWindow 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QtOtherModuleExamples 2 | Qt其他模块相关类库范例,Qt Network,Qt SQL,Qt Test,Qt Charts等 3 | * 范例详解请见个人博客--Blog:[http://techieliang.com](http://techieliang.com/) 4 | 5 | ## QTcpSocketExample 6 | Qt进行tcp通讯的简单范例,范例中户端和服务端直接写在了一起实现收发 7 | * Blog:[QTcpSocket-Qt使用Tcp通讯实现服务端和客户端](http://techieliang.com/2017/12/530/) 8 | 9 | ## QUdpSocketExample 10 | Qt进行udp通讯的简单范例,范例中户端和服务端直接写在了一起实现收发 11 | * Blog:[QUdpSocket-Qt使用Udp通讯实现服务端和客户端](http://techieliang.com/2017/12/532/) 12 | 13 | ## QNetworkAccessManagerReadHttp 14 | Qt进行http通讯,仅提供get方法,put/post近似 15 | * Blog:[Qt使用QNetworkAccessManager实现Http操作](http://techieliang.com/2017/12/649/) 16 | ![pic](https://github.com/TechieL/MyBlogPictureBackup/blob/master/%E5%9B%BE%E7%89%87/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/Qt%E4%BD%BF%E7%94%A8QNetworkAccessManager%E5%AE%9E%E7%8E%B0Http%E6%93%8D%E4%BD%9C/1.png) 17 | 18 | ## QtConcurrentExample(Blog) 19 | Qt使用QtConcurrent并行计算高级API范例,请直接看博客 20 | 其余多线程相关请看[QtCoreExamples 21 | ](https://github.com/TechieL/QtCoreExamples#qthreadexampleblog) 22 | * Blog:[Qt多线程-QtConcurrent并行运算高级API](http://techieliang.com/2017/12/608/) 23 | * Blog:[Qt多线程-总结QThread-QThreadPool-QtConcurrent](http://techieliang.com/2017/12/616/) 24 | 25 | ## SupportMulticlientsTcpserver 26 | Qt使用QTcpserver实现多客户端连接管理 27 | * Blog:[QTcpServer实现多客户端连接](http://techieliang.com/2017/12/760/) 28 | ![pic](https://github.com/TechieL/MyBlogPictureBackup/raw/master/%E5%9B%BE%E7%89%87/%E6%96%87%E7%AB%A0%E5%9B%BE%E7%89%87/QTcpServer%E5%AE%9E%E7%8E%B0%E5%A4%9A%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BF%9E%E6%8E%A5/gif.gif) -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/SupportMulticlientsTcpserver.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-12-21T12:58:45 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui network 8 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 9 | 10 | TARGET = SupportMulticlientsTcpserver 11 | TEMPLATE = app 12 | 13 | # The following define makes your compiler emit warnings if you use 14 | # any feature of Qt which has been marked as deprecated (the exact warnings 15 | # depend on your compiler). Please consult the documentation of the 16 | # deprecated API in order to know how to port your code away from it. 17 | DEFINES += QT_DEPRECATED_WARNINGS 18 | 19 | # You can also make your code fail to compile if you use deprecated APIs. 20 | # In order to do so, uncomment the following line. 21 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 22 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 23 | 24 | 25 | SOURCES += \ 26 | main.cpp \ 27 | mainwindow.cpp \ 28 | tcp_server.cpp \ 29 | tcp_server_private.cpp 30 | 31 | HEADERS += \ 32 | mainwindow.h \ 33 | tcp_server.h \ 34 | tcp_server_private.h 35 | 36 | FORMS += \ 37 | mainwindow.ui 38 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | #include 5 | 6 | MainWindow::MainWindow(QWidget *parent) : 7 | QMainWindow(parent), 8 | ui(new Ui::MainWindow) { 9 | ui->setupUi(this); 10 | connect(this, &MainWindow::ServerRecved, this, MainWindow::ServerRecvedSlot); 11 | model_ = new QStandardItemModel(this); 12 | ui->tableView->setModel(model_); 13 | ui->tableView->setColumnWidth(0,400); 14 | tcp_server_ = new TcpServer(this); 15 | if(!tcp_server_->listen(QHostAddress::Any, 8000)) { 16 | qDebug()<errorString(); //错误信息 17 | return; 18 | } 19 | qDebug()<<"listening"; //错误信息 20 | model_->insertRow(0,new QStandardItem("listening")); 21 | connect(tcp_server_, 22 | &TcpServer::ClientConnected, 23 | this, 24 | &MainWindow::ClientConnected);//监听 25 | connect(tcp_server_, 26 | &TcpServer::ClientDisconnected, 27 | this, 28 | &MainWindow::ClientDisconnected);//监听 29 | } 30 | 31 | MainWindow::~MainWindow() { 32 | tcp_server_->close(); 33 | delete ui; 34 | } 35 | 36 | void MainWindow::ClientConnected(qintptr handle, QTcpSocket* socket) { 37 | model_->insertRow(0,new QStandardItem(QString::number(handle)+" connected")); 38 | connect(socket, &QTcpSocket::readyRead, 39 | [=]() { 40 | emit ServerRecved(handle, socket, socket->readAll()); 41 | }); 42 | } 43 | 44 | void MainWindow::ClientDisconnected(qintptr handle) { 45 | model_->insertRow(0,new QStandardItem(QString::number(handle)+" disconnected")); 46 | } 47 | 48 | void MainWindow::ServerRecvedSlot(qintptr handle, 49 | QTcpSocket *socket, 50 | const QByteArray &data) { 51 | Q_UNUSED(handle); 52 | qDebug()<peerAddress().toString()<peerPort()<peerAddress().toString()). 55 | arg(socket->peerPort()). 56 | arg(QString(data)); 57 | model_->insertRow(0,new QStandardItem(send_data)); 58 | socket->write(send_data.toLatin1()); 59 | } 60 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include "tcp_server.h" 7 | namespace Ui { 8 | class MainWindow; 9 | } 10 | 11 | class MainWindow : public QMainWindow 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit MainWindow(QWidget *parent = 0); 17 | ~MainWindow(); 18 | signals: 19 | void ServerRecved(qintptr, QTcpSocket*, const QByteArray &); 20 | private slots: 21 | void ClientConnected(qintptr handle, QTcpSocket *socket); 22 | void ClientDisconnected(qintptr handle); 23 | /** 24 | * @brief 服务端收到消息的信号 25 | * 若想要统一管理或做日志处理可连接此信号 26 | * @param 收到消息的连接句柄 27 | * @param 收到消息的socket指针 28 | * @param 收到的消息内容 29 | */ 30 | void ServerRecvedSlot(qintptr handle, QTcpSocket *socket, const QByteArray &data); 31 | private: 32 | Ui::MainWindow *ui; 33 | TcpServer *tcp_server_; 34 | QStandardItemModel *model_; 35 | }; 36 | 37 | #endif // MAINWINDOW_H 38 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 568 10 | 398 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/tcp_server.cpp: -------------------------------------------------------------------------------- 1 | #include "tcp_server.h" 2 | #include "tcp_server_private.h" 3 | //构造函数 4 | TcpServer::TcpServer(QObject *parent) 5 | : QTcpServer(parent), 6 | private_(new tcp_server_private::TcpServerPrivate) { 7 | } 8 | //析构函数 9 | TcpServer::~TcpServer() { 10 | for(tcp_server_private::TcpSocket *client : private_->clients.values()) { 11 | client->disconnectFromHost(); 12 | auto handle = client->socketDescriptor(); 13 | client->deleteLater(); 14 | //告知其他调用者 当前socket断开,避免有需要在socket后执行的方法 15 | emit ClientDisconnected(handle); 16 | } 17 | if(private_) 18 | delete private_; 19 | this->close(); 20 | } 21 | //重写-有连接到来 22 | void TcpServer::incomingConnection(qintptr handle) { 23 | //超出最大练级数量关闭连接 24 | if (private_->clients.size() > maxPendingConnections()) { 25 | QTcpSocket tcp; 26 | tcp.setSocketDescriptor(handle); 27 | tcp.disconnectFromHost(); 28 | return; 29 | } 30 | auto client_socket = new tcp_server_private::TcpSocket(handle); 31 | Q_ASSERT(client_socket->socketDescriptor() == handle); 32 | //socket断开连接的信号与server槽连接 33 | connect(client_socket, 34 | &tcp_server_private::TcpSocket::ClientDisconnected, 35 | this, 36 | &TcpServer::ClientDisconnectedSlot); 37 | //主动断开连接的操作 38 | connect(this, 39 | &TcpServer::InitiativeDisConnectClient, 40 | client_socket, 41 | &tcp_server_private::TcpSocket::DisconnectSocket); 42 | //map记录 43 | private_->clients.insert(handle, client_socket); 44 | qDebug()<clients.remove(handle); 51 | qDebug()< 4 | namespace tcp_server_private { 5 | class TcpServerPrivate; 6 | } 7 | class QTcpSocket; 8 | /** 9 | * @brief Tcp多客户端服务器 10 | */ 11 | class TcpServer : public QTcpServer { 12 | Q_OBJECT 13 | public: 14 | /** 15 | * @brief 构造函数 16 | * @param parent 父QObject 17 | */ 18 | explicit TcpServer(QObject *parent = Q_NULLPTR); 19 | /** 20 | * @brief 析构函数 21 | * 非多线程模式行为:关闭所有连接后析构 22 | * 多线程模式行为:关闭所有连接及线程池后析构 23 | */ 24 | ~TcpServer(); 25 | signals: 26 | /** 27 | * @brief 客户端连入 28 | * @param 连接句柄 29 | * @param socket指针 30 | */ 31 | void ClientConnected(qintptr, QTcpSocket*);//发送新用户连接信息 32 | /** 33 | * @brief socket已断开连接 34 | * 若需要在socket后析构后进行操作的可连接此信号 35 | * @param 连接句柄 36 | */ 37 | void ClientDisconnected(qintptr); 38 | /** 39 | * @brief 主动断开连接信号 40 | * 若服务端想要主动断开与客户端连接将会发出此信号 41 | * 此信号发出这表明进行断开操作不表明断开成功,成功以SocketDisconnected信号为准 42 | * @param 连接句柄 43 | */ 44 | void InitiativeDisConnectClient(qintptr); 45 | protected slots: 46 | /** 47 | * @brief 客户端已断开槽 48 | * 此槽与客户端的已断开信号连接 49 | * @param handle 50 | */ 51 | void ClientDisconnectedSlot(qintptr handle); 52 | protected: 53 | /** 54 | * @brief 重写-有连接到来 55 | * 连接到来不一定连接,会根据maxPendingConnections决定是否连接 56 | * @param handle 连接句柄 57 | */ 58 | virtual void incomingConnection(qintptr handle); 59 | private: 60 | tcp_server_private::TcpServerPrivate *private_; 61 | }; 62 | #endif // TCP_SERVER_H 63 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/tcp_server_private.cpp: -------------------------------------------------------------------------------- 1 | #include "tcp_server_private.h" 2 | namespace tcp_server_private { 3 | //构造函数 4 | TcpSocket::TcpSocket(qintptr handle, QObject *parent) 5 | : QTcpSocket(parent), handle_(handle) { 6 | this->setSocketDescriptor(handle_); 7 | //断开连接消息 8 | connect(this,&TcpSocket::disconnected, 9 | [&](){ 10 | this->deleteLater(); 11 | emit this->ClientDisconnected(handle_); 12 | }); 13 | } 14 | //主动断开连接槽 15 | void TcpSocket::DisconnectSocket(qintptr handle) { 16 | if (handle == handle_) 17 | disconnectFromHost(); 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /SupportMulticlientsTcpserver/tcp_server_private.h: -------------------------------------------------------------------------------- 1 | #ifndef TCP_SERVER_PRIVATE_H 2 | #define TCP_SERVER_PRIVATE_H 3 | #include 4 | namespace tcp_server_private { 5 | class TcpSocket : public QTcpSocket { 6 | Q_OBJECT 7 | public: 8 | /** 9 | * @brief 构造函数 10 | * @param socketDescriptor 连接句柄 11 | * @param parent 父QObject 12 | */ 13 | TcpSocket(qintptr handle, QObject *parent = 0); 14 | signals: 15 | /* 16 | * 已断开连接信号 17 | */ 18 | void ClientDisconnected(qintptr); 19 | public slots: 20 | /** 21 | * @brief 断开连接 22 | * @param handle 连接句柄 23 | */ 24 | void DisconnectSocket(qintptr handle); 25 | private: 26 | qintptr handle_; 27 | }; 28 | /** 29 | * @brief Tcp多客户端服务器私有类 30 | */ 31 | class TcpServerPrivate { 32 | public: 33 | QMap clients; ///所有连接的map 34 | }; 35 | }//tcp_server_private 36 | #endif // TCP_SERVER_PRIVATE_H 37 | --------------------------------------------------------------------------------