135 lines
3.6 KiB
C++
135 lines
3.6 KiB
C++
#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);
|
|
}
|