Qt TCP通信 例子
效果
流程
通信分为服务器
和客户端
服务器
- 实例化一个服务器对象
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();
客户端
- 实例化与服务器通信的套接字对象
// 通信的套接字对象
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();
代码
服务器代码
.h
#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; // 保存和所有客户端通信的套接字
};
.cpp
#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;
};
.cpp
#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);
}