culturered_client/ProjectorDisplay/TcpClient.cpp

135 lines
3.6 KiB
C++
Raw Permalink Normal View History

2024-09-07 03:34:44 +00:00
#include "TcpClient.h"
#include "MainWindow.h"
TcpClient::TcpClient(QObject* parent)
: QObject(parent) {
m_socket = new QTcpSocket(this);
// 连接信号槽
connect(m_socket, &QTcpSocket::connected, this, &TcpClient::OnConnected);
connect(m_socket, &QTcpSocket::disconnected, this, &TcpClient::OnDisconnected);
connect(m_socket, &QTcpSocket::readyRead, this, &TcpClient::OnReadyRead);
connect(m_socket, &QTcpSocket::stateChanged, this, &TcpClient::OnStateChanged);
connect(m_socket, &QTcpSocket::errorOccurred, this, &TcpClient::OnError);
// 设置心跳定时器
m_heartbeatTimer = new QTimer(this);
connect(m_heartbeatTimer, &QTimer::timeout, this, &TcpClient::SendHeartbeat);
m_connectTimer = new QTimer(this);
connect(m_connectTimer, &QTimer::timeout, this, &TcpClient::OnConntectTimeout);
}
TcpClient::~TcpClient() {
disconnect();
delete m_socket;
delete m_heartbeatTimer;
}
bool TcpClient::ConnectToServer(const QString& address) {
const auto state = m_socket->state();
if (QAbstractSocket::UnconnectedState != state) {
return true;
}
QStringList ipAndPort = address.split(":");
if (ipAndPort.size() != 2) {
return false;
}
m_ip = ipAndPort[0];
m_port = ipAndPort[1].toInt();
m_socket->connectToHost(QHostAddress(m_ip), m_port);
return m_socket->waitForConnected();
}
void TcpClient::Disconnect() {
m_socket->disconnectFromHost();
m_heartbeatTimer->stop();
}
bool TcpClient::IsConnected() const {
return QAbstractSocket::ConnectedState == m_socket->state();
}
bool TcpClient::IsNeedConnect() const {
return QAbstractSocket::UnconnectedState == m_socket->state();
}
void TcpClient::OnConnected() {
qDebug() << "Connected to server";
m_connectTimer->stop();
// 启动心跳定时器
m_heartbeatTimer->start(5000); // 每 5 秒发送一次
MainWindow::Get().SetNetStatus(1);
}
void TcpClient::OnDisconnected() {
qDebug() << "Disconnected from server";
m_connectTimer->start(3000);
}
void TcpClient::OnReadyRead() {
QTcpSocket* tcpSocket = static_cast<QTcpSocket*>(sender());
QDataStream receiveStream(tcpSocket);
receiveStream.setVersion(QDataStream::Qt_6_2);
QByteArray message;
receiveStream >> message;
QString cmd = QString::fromUtf8(message);
qDebug() << "message: " << cmd;
Q_EMIT MessageReceivered(cmd);
}
void TcpClient::OnStateChanged(QAbstractSocket::SocketState state) {
if (QAbstractSocket::SocketState::ConnectedState == state) {
m_connectTimer->start(3000);
}
}
void TcpClient::OnError(QAbstractSocket::SocketError error) {
qDebug() << "Socket error: " << m_socket->errorString();
if (!m_connectTimer->isActive()) {
m_connectTimer->start(3000);
}
MainWindow::Get().SetNetStatus(0);
}
void TcpClient::SendHeartbeat() {
// 发送心跳数据
QString heartbeatMsg = "Heartbeat";
QByteArray sendData;
QDataStream sendStream(&sendData, QIODevice::WriteOnly);
// 设置版本号,可根据需求进行修改
sendStream.setVersion(QDataStream::Qt_6_2);
int messageSize = heartbeatMsg.toUtf8().size();
// 写入包的大小
sendStream << messageSize;
// 写入实际数据
sendStream.writeRawData(heartbeatMsg.toUtf8().constData(), messageSize);
// 发送
m_socket->write(sendData);
m_socket->flush();
}
void TcpClient::OnConntectTimeout() {
if (QAbstractSocket::ConnectingState == m_socket->state() ||
QAbstractSocket::ConnectedState == m_socket->state()) {
return;
}
m_socket->connectToHost(m_ip, m_port);
}