通讯分为服务器
和客户端
服务器服务器
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); }