Qt网络编程-简易版TcpServer入门Demo(2)
生活随笔
收集整理的這篇文章主要介紹了
Qt网络编程-简易版TcpServer入门Demo(2)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Qt網(wǎng)絡編程-簡易版TcpServer入門Demo(2)🦏
文章目錄
- Qt網(wǎng)絡編程-簡易版TcpServer入門Demo(2)🦏
- 1、概述🐅
- 2、TCP服務端流程圖🐴
- 3、 關鍵信號🐕
- 4、 關鍵函數(shù) 🐶
- 5、主要代碼🦍
- 6、實現(xiàn)效果🐒
- 7、源代碼🐈
| 👉個人內(nèi)容分類匯總 👈 |
| 👉Qt網(wǎng)絡編程-簡易版TcpClient入門Demo(1)👈 |
| 👉Qt網(wǎng)絡編程-簡易版TcpServer入門Demo(2)👈 |
| 👉Qt網(wǎng)絡編程-簡易版UDP單播通信入門Demo(3)👈 |
| 👉Qt網(wǎng)絡編程-簡易版UDP單播通信入門Demo(4)👈 |
| 👉Qt網(wǎng)絡編程-簡易版UDP組播通信入門Demo(5)👈 |
| 👉Qt網(wǎng)絡編程-TcpClient入門Demo(1)👈 |
| 👉Qt網(wǎng)絡編程-TcpServer入門Demo(2)👈 |
1、概述🐅
| 使用QTcpServer實現(xiàn)TCP Server,十分簡易的入門Demo |
第一,絕對不意氣用事;
第二,絕對不放過任何一個注釋;
第三,絕對保證代碼的簡潔明了。🤘
為了便于學習,在這個Demo里會盡可能簡單的實現(xiàn)TCP服務端功能,盡可能少的引入其它功能,只保留了基本功能,所以可能會有一些bug。
實現(xiàn)功能:
- 監(jiān)聽1個Tcp客戶端連接功能,多余的連接自動斷開;
- 數(shù)據(jù)接收功能;
- 數(shù)據(jù)發(fā)送功能
2、TCP服務端流程圖🐴
- TCP服務端除了監(jiān)聽連接部分外,其它的和TCP客戶端基本一樣。
3、 關鍵信號🐕
| newConnection | QTcpServer監(jiān)聽到新的客戶端連接 |
| disconnected | QTcpSocket斷開連接后發(fā)出此信號 |
| readyRead | QTcpSocket有可讀數(shù)據(jù)時發(fā)出此信號 |
4、 關鍵函數(shù) 🐶
| isListening | 判斷是否正在監(jiān)聽連接 |
| listen | 綁定服務器偵聽地址和端口上的傳入連接。如果端口為0,則會自動選擇一個端口。(相當于bind + listen ) |
| nextPendingConnection | 返回已連接的QTcpSocket,如果有已連接的QTcpSocket沒調(diào)用這個函數(shù)返回,將在QTcpServer釋放時會自動統(tǒng)一釋放(所以存在一定的內(nèi)存泄漏問題) |
| close | 關閉服務器。 服務器將不再監(jiān)聽傳入連接 |
5、主要代碼🦍
-
注意:在.pro文件里添加QT += network,否則編譯失敗。
-
.h文件
/******************************************************************************* @文件名 simpletcpserver.h* @功能 簡易的TCP服務端Demo,只保留接聽TCP(1個)客戶端連接/斷開、 數(shù)據(jù)發(fā)送、接收功能** @開發(fā)者 mhf* @郵箱 1603291350@qq.com* @時間 2022/04/17* @備注*****************************************************************************/ #ifndef SIMPLETCPSERVER_H #define SIMPLETCPSERVER_H#include <QWidget> #include <QTcpServer>namespace Ui { class SimpleTcpServer; }class SimpleTcpServer : public QWidget {Q_OBJECTpublic:explicit SimpleTcpServer(QWidget *parent = nullptr);~SimpleTcpServer();private slots:void on_newConnection();void on_disconnected();void on_readyRead();void on_but_connect_clicked();void on_but_send_clicked();private:Ui::SimpleTcpServer *ui;QTcpServer* m_server = nullptr; // TCP服務端對象QTcpSocket* m_client = nullptr; // 連接成功的客戶端 };#endif // SIMPLETCPSERVER_H -
.cpp文件
#include "simpletcpserver.h" #include "ui_simpletcpserver.h"#include <qtcpsocket.h>SimpleTcpServer::SimpleTcpServer(QWidget *parent) :QWidget(parent),ui(new Ui::SimpleTcpServer) {ui->setupUi(this);this->setWindowTitle("簡易版本TCP 服務端Demo");m_server = new QTcpServer(this);connect(m_server, &QTcpServer::newConnection, this, &SimpleTcpServer::on_newConnection); // 監(jiān)聽新的客戶端連接 }SimpleTcpServer::~SimpleTcpServer() {delete ui; }void SimpleTcpServer::on_but_connect_clicked() {if(!m_server->isListening()) // 判斷是否正在監(jiān)聽連接{// 告訴服務器偵聽地址和端口上的傳入連接。如果端口為0,則會自動選擇一個端口。// 如果地址是QHostAddress::Any,服務器將監(jiān)聽所有網(wǎng)絡接口。bool ret = m_server->listen(QHostAddress::Any, ui->spin_localPort->value());if(ret){ui->but_connect->setText("停止");}else{qDebug() << QString("tcpServer綁定監(jiān)聽IP、端口失敗:%1 %2").arg(m_server->errorString()).arg(m_server->serverError());}}else{m_client->abort();m_server->close();ui->but_connect->setText("開始監(jiān)聽");} }/*** @brief 如果有新的TCP客戶端發(fā)起連接,則會在這個函數(shù)中返回連接成功的QTcpSocket;* 這里只保留第一個連接成功的客戶端,其它的自動斷開連接*/ void SimpleTcpServer::on_newConnection() {QTcpSocket* tcpSocket = m_server->nextPendingConnection(); // 存在內(nèi)存泄漏,最好使用時通過hasPendingConnections判斷是否有未返回的連接if(tcpSocket){if(m_client) // 如果已經(jīng)有連接的 客戶端,則斷開后面所有的連接{tcpSocket->deleteLater();return;}m_client = tcpSocket;connect(tcpSocket, &QTcpSocket::disconnected, this, &SimpleTcpServer::on_disconnected); // 斷開連接connect(tcpSocket, &QTcpSocket::readyRead, this, &SimpleTcpServer::on_readyRead); // 接收客戶端發(fā)來的數(shù)據(jù)} }/*** @brief 斷開連接*/ void SimpleTcpServer::on_disconnected() {disconnect(m_client, &QTcpSocket::disconnected, this, &SimpleTcpServer::on_disconnected); // 斷開綁定的信號槽disconnect(m_client, &QTcpSocket::readyRead, this, &SimpleTcpServer::on_readyRead);//delete m_client; // 這里不能用delete,否則在vs里會報錯 0x00007FFBF870A1CE (Qt5Networkd.dll)處(位于 QMNetwork.exe 中)引發(fā)的異常: 0xC0000005: 讀取位置 0xFFFFFFFFFFFFFFFF 時發(fā)生訪問沖突。QTcpSocket* tcpSocket = m_client;m_client = nullptr; // 先將m_client置空,因為deleteLater不會置空tcpSocket->deleteLater(); // 移除已經(jīng)斷開連接的Client(注意這里不能使用delete,否則在vs中會報錯),但這種方式不會置為 空 }/*** @brief 接收數(shù)據(jù),這里和TCP Client是一樣的*/ void SimpleTcpServer::on_readyRead() {QByteArray dataArr = m_client->readAll(); // 一次性讀取緩存中所有數(shù)據(jù)if(dataArr.count() <= 0) // 沒有讀取到數(shù)據(jù){return;}ui->text_recv->append(dataArr); // 顯示讀取到的數(shù)據(jù) }/*** @brief 發(fā)送數(shù)據(jù),這里和TCP Client是一樣的*/ void SimpleTcpServer::on_but_send_clicked() {if(!m_client) return; // 判斷是否為空,如果為空則未連接if(m_client->state() != QAbstractSocket::ConnectedState) return; // 判斷TCP是否已連接,如果沒有連接則不發(fā)送數(shù)據(jù)QString str = ui->text_send->toPlainText(); // 獲取輸入框的內(nèi)容qint64 len = m_client->write(str.toUtf8()); // 發(fā)送數(shù)據(jù),toUtf8()是為了支持發(fā)送中文,但是如果接收端編碼方式不同則中文可能顯示亂碼if(len < 0){qWarning() <<"發(fā)送失敗!";} }
6、實現(xiàn)效果🐒
7、源代碼🐈
gitee
github
總結(jié)
以上是生活随笔為你收集整理的Qt网络编程-简易版TcpServer入门Demo(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重学java基础第二十课:环境配置和第一
- 下一篇: 前端学习(3326):闭包的形式1