通訊分爲服務器
和客戶端
服務器服務器
pServer = new QTcpServer;
newConnection
信號,當有新的客戶端鏈接時,會發送該信號connect(pServer, &QTcpServer::newConnection, this, &TCP::slo_newConnection);
pServer->listen(QHostAddress("127.0.0.1"), 8848);
newConnection
信號,對應的槽函數中獲取與對應客戶端通訊的套接字對象// 獲取與客戶端通訊的套接字對象 QTcpSocket * tcpSocket = pServer->nextPendingConnection();
readyRead
信號,接收客戶端信息,關聯套接字的disconnected
信號,處理客戶端斷開鏈接// 綁定信號 ,接收客戶端消息 connect(tcpSocket, &QTcpSocket::readyRead, this, &TCP::slo_readMsg); // 客戶端斷開鏈接 connect(tcpSocket, &QTcpSocket::disconnected,this,&TCP::slo_clientDisConn);
// 遍歷全部客戶端套接字 for (auto socket : mSokets) { socket->write(ui->lineEdit_3->text().toUtf8()); }
close()
pServer->close();
客戶端app
// 通訊的套接字對象 pSokcet = new QTcpSocket(this);
readyRead
信號,接收服務器信息// 關聯信號 ,接收服務端的消息 connect(pSokcet, &QTcpSocket::readyRead, this, &TCP_Client::slo_readMsg);
pSokcet->connectToHost(QHostAddress("127.0.0.1"), 8848);
pSokcet->write(ui.lineEdit_3->text().toUtf8());
QString msg = QString::fromUtf8(pSokcet->readAll());
pSokcet->close();
服務器代碼
.hsocket
#pragma once #include <QWidget> #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> namespace Ui { class TCP; }; class TCP : public QWidget { Q_OBJECT public: TCP(QWidget *parent = Q_NULLPTR); ~TCP(); private slots: void slo_newConnection(); // 新客戶端鏈接 void slo_clientDisConn(); // 客戶端斷開鏈接 void slo_listenerStart(); // 開啓監聽 void slo_listenerStop(); // 關閉監聽 void slo_replyAll(); // 回覆全部客戶端 void slo_readMsg(); // 接收客戶端消息 private: void init(); // 初始化 void updateMsg(const QString & msg); // 更新消息 private: Ui::TCP *ui; QTcpServer * pServer; // 服務器對象 QList<QTcpSocket*> mSokets; // 保存和全部客戶端通訊的套接字 };
.cpptcp
#include <QDateTime> #include <QHostAddress> #include "TCP.h" #include "ui_TCP.h" TCP::TCP(QWidget *parent) : QWidget(parent) ,ui(new Ui::TCP()) { ui->setupUi(this); init(); } TCP::~TCP() { delete ui; } void TCP::slo_newConnection() { // 獲取與客戶端通訊的套接字對象 QTcpSocket * tcpSocket = pServer->nextPendingConnection(); // 綁定信號 ,接收客戶端消息 connect(tcpSocket, &QTcpSocket::readyRead, this, &TCP::slo_readMsg); // 客戶端斷開鏈接 connect(tcpSocket, &QTcpSocket::disconnected,this,&TCP::slo_clientDisConn); // 保存套接字 mSokets << tcpSocket; // 更新消息 QString msg = QStringLiteral("新用戶鏈接"); updateMsg(msg); } void TCP::slo_clientDisConn() { // 與客戶端通訊的套接字對象 QTcpSocket * tcpSocket = qobject_cast<QTcpSocket*>(QObject::sender()); // 移除 mSokets.removeOne(tcpSocket); // 更新日誌 tcpSocket->disconnect(tcpSocket, 0, this, 0); QString msg = QStringLiteral("IP:%1的用戶斷開鏈接").arg(tcpSocket->peerAddress().toString()); updateMsg(msg); tcpSocket->deleteLater(); } void TCP::slo_listenerStart() { if (pServer->isListening()) { QString msg = QStringLiteral("監聽已經打開,請先關閉當前監聽"); updateMsg(msg); return; } if (pServer->listen(QHostAddress(ui->lineEdit->text()), ui->lineEdit_2->text().toInt())) { QString msg = QStringLiteral("打開監聽成功"); msg += QStringLiteral(",監聽IP::"); msg += ui->lineEdit->text(); msg += QStringLiteral(",監聽Port:"); msg += ui->lineEdit_2->text(); updateMsg(msg); } else { updateMsg(QStringLiteral("打開監聽失敗")); } } void TCP::slo_listenerStop() { if (pServer->isListening()) { pServer->close(); mSokets.clear(); updateMsg(QStringLiteral("關閉監聽成功")); } else { updateMsg(QStringLiteral("沒有監聽,不要重複關閉")); } } void TCP::slo_replyAll() { if (mSokets.isEmpty()) { updateMsg(QStringLiteral("尚未客戶端鏈接")); return; } for (auto socket : mSokets) { socket->write(ui->lineEdit_3->text().toUtf8()); } } void TCP::slo_readMsg() { // 與客戶端通訊的套接字對象 QTcpSocket * tcpSocket = qobject_cast<QTcpSocket*>(QObject::sender()); // 接收消息 QString msg = QString::fromUtf8(tcpSocket->readAll()); // 顯示 updateMsg(msg); } void TCP::init() { // 初始化服務器對象 pServer = new QTcpServer; // 關聯newConnection信號,當有新的客戶端鏈接時,會觸發此信號 connect(pServer, &QTcpServer::newConnection, this, &TCP::slo_newConnection); } void TCP::updateMsg(const QString & msg) { QString string = QStringLiteral("【%1】").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); string.append(msg); ui->textEdit->append(string); }
客戶端
.h函數
#pragma once #include "ui_TCP_Client.h" #include <QWidget> #include <QtNetwork/QTcpSocket> #include <QHostAddress> #include <QString> class TCP_Client : public QWidget { Q_OBJECT public: TCP_Client(QWidget *parent = Q_NULLPTR); ~TCP_Client(); private slots: void slo_connectToHost(); // 接連 void slo_disConnect(); // 斷開接連 void slo_sendMsg(); // 發送消息 void slo_readMsg(); // 接收消息 private: void init(); // 初始化 void updateMsg(const QString& msg); // 更新消息 private: Ui::TCP_Client ui; QTcpSocket * pSokcet; };
.cppui
#include "TCP_Client.h" #include <QDateTime> TCP_Client::TCP_Client(QWidget *parent) : QWidget(parent) { ui.setupUi(this); init(); } TCP_Client::~TCP_Client() { } void TCP_Client::slo_connectToHost() { if (QTcpSocket::ConnectedState == pSokcet->state()) { updateMsg(QStringLiteral("已經鏈接,不用重複鏈接")); } else if (QTcpSocket::UnconnectedState == pSokcet->state()) { pSokcet->connectToHost(QHostAddress(ui.lineEdit->text()), ui.lineEdit_2->text().toInt()); updateMsg(QStringLiteral("鏈接成功")); } } void TCP_Client::slo_disConnect() { if (QTcpSocket::UnconnectedState == pSokcet->state()) { updateMsg(QStringLiteral("未鏈接,不用重複斷開")); } else if (QTcpSocket::ConnectedState == pSokcet->state()) { pSokcet->close(); updateMsg(QStringLiteral("已斷開")); } } void TCP_Client::slo_sendMsg() { pSokcet->write(ui.lineEdit_3->text().toUtf8()); } void TCP_Client::slo_readMsg() { // 套接字對象 QString msg = QString::fromUtf8(pSokcet->readAll()); // 顯示 updateMsg(msg); } void TCP_Client::init() { // 通訊的套接字對象 pSokcet = new QTcpSocket(this); // 關聯信號 ,接收服務端的消息 connect(pSokcet, &QTcpSocket::readyRead, this, &TCP_Client::slo_readMsg); } void TCP_Client::updateMsg(const QString& msg) { QString string = QStringLiteral("【%1】").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); string.append(msg); ui.textEdit->append(string); }