#include "MyTcpClient.h" #include MyTcpClient* MyTcpClient::m_instance = nullptr; MyTcpClient::MyTcpClient(QObject *parent) : QObject(parent), shouldReconnect(true) { socket = new QTcpSocket(this); connect(socket, &QTcpSocket::connected, this, &MyTcpClient::onConnected); connect(socket, &QTcpSocket::readyRead, this, &MyTcpClient::onReadyRead); connect(socket, &QTcpSocket::disconnected, this, &MyTcpClient::onDisconnected); //connect(socket, &QTcpSocket::errorOccurred, this, &MyTcpClient::onErrorOccurred); // 连接失败后,定时尝试重连 connect(&reconnectTimer, &QTimer::timeout, this, &MyTcpClient::onReconnect); reconnectTimer.setInterval(5000); // 5秒重连一次 memset(header,0,sizeof(header)); int packge_len = 0; } MyTcpClient::~MyTcpClient() { shouldReconnect = false; if (socket) { socket->disconnectFromHost(); socket->deleteLater(); } } MyTcpClient* MyTcpClient::instance() { if (!m_instance) { m_instance = new MyTcpClient(); } return m_instance; } void MyTcpClient::connectToServer(const QString &host, quint16 port) { serverHost = host; serverPort = port; if (socket->state() == QAbstractSocket::ConnectedState) { qDebug() << "Already connected!"; return; } qDebug() << "Connecting to" << host << ":" << port; socket->connectToHost(host, port); if (!socket->waitForConnected()) { qDebug() << "Connection failed!"; return; } } int MyTcpClient::sendData(char*data,qint64 len) { qint64 bytesWritten = socket->write(data, len); socket->waitForBytesWritten(); return bytesWritten; } void MyTcpClient::waitForRead() { socket->waitForReadyRead(); } void MyTcpClient::disconnectFromServer() { shouldReconnect = false; // 停止自动重连 reconnectTimer.stop(); heartbeatTimer.stop(); socket->disconnectFromHost(); } void MyTcpClient::onConnected() { qDebug() << "Connected to server!"; emit connected(); reconnectTimer.stop(); // 连接成功,停止自动重连 heartbeatTimer.start(); // 开始发送心跳包 } void MyTcpClient::onReadyRead() { m_buffer.append(socket->readAll()); while (true) { if (m_buffer.size() < sizeof(BaseHeader)) return; const BaseHeader *base = reinterpret_cast(m_buffer.constData()); if (!(base->head[0] == 0xAA && base->head[1] == 0x55 && base->head[2] == 0xAA)) { m_buffer.remove(0, 1); continue; } uint8_t cmd = base->cmd; if (cmd == kDownloadConfigFile) { if (m_buffer.size() < sizeof(BaseHeader) + sizeof(LargeHeaderExtra)) return; // 等待更多数据 const LargeHeaderExtra *extra = reinterpret_cast( m_buffer.constData() + sizeof(BaseHeader)); int payloadLen = extra->len; if (payloadLen <= 0 || payloadLen > 10 * 1024 * 1024) { qWarning() << "Detected abnormal payload length:" << payloadLen; m_buffer.remove(0, sizeof(BaseHeader)); // 丢弃当前包头 continue; } int totalLen = sizeof(BaseHeader) + sizeof(LargeHeaderExtra) + extra->len; if (m_buffer.size() < totalLen) return; // 等待完整数据到达 emit dataReceived( m_buffer); m_buffer.remove(0, totalLen); }else if(cmd == kGetLogInfo){ if (m_buffer.size() < sizeof(GetSubCardLogRsp)) return; // 等待更多数据 const GetSubCardLogRsp *extra = reinterpret_cast(m_buffer.constData()); int payloadLen = extra->len; if (payloadLen <= 0 || payloadLen > 10 * 1024 * 1024) { qWarning() << "Detected abnormal payload length:" << payloadLen; m_buffer.remove(0, sizeof(BaseHeader)); // 丢弃当前包头 continue; } int totalLen = sizeof(GetSubCardLogRsp) + extra->len; if (m_buffer.size() < totalLen) return; // 等待完整数据到达 emit dataReceived( m_buffer); m_buffer.remove(0, totalLen); } else { QByteArray fullData = m_buffer; emit dataReceived(fullData); m_buffer.clear(); return; // 等待下一批数据 } } } void MyTcpClient::onDisconnected() { qDebug() << "Disconnected from server!"; emit disconnected(); if (shouldReconnect) { qDebug() << "Attempting to reconnect in 5 seconds..."; reconnectTimer.start(); // 触发自动重连 heartbeatTimer.stop(); // 断开后停止心跳 } } void MyTcpClient::onErrorOccurred(QAbstractSocket::SocketError socketError) { Q_UNUSED(socketError) qDebug() << "Socket error:" << socket->errorString(); emit errorOccurred(socket->errorString()); } void MyTcpClient::onReconnect() { if (socket->state() == QAbstractSocket::UnconnectedState) { qDebug() << "Reconnecting to" << serverHost << ":" << serverPort; socket->connectToHost(serverHost, serverPort); } }