| 
									
										
										
										
											2025-03-13 15:12:03 +08:00
										 |  |  | #include "MyTcpClient.h"
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-20 14:38:14 +08:00
										 |  |  | MyTcpClient* MyTcpClient::m_instance = nullptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-13 15:12:03 +08:00
										 |  |  | 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秒重连一次
 | 
					
						
							| 
									
										
										
										
											2025-05-14 23:14:50 +08:00
										 |  |  |     memset(header,0,sizeof(header)); | 
					
						
							|  |  |  |     int packge_len = 0; | 
					
						
							| 
									
										
										
										
											2025-03-13 15:12:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MyTcpClient::~MyTcpClient() { | 
					
						
							|  |  |  |     shouldReconnect = false; | 
					
						
							|  |  |  |     if (socket) { | 
					
						
							|  |  |  |         socket->disconnectFromHost(); | 
					
						
							|  |  |  |         socket->deleteLater(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-03-20 14:38:14 +08:00
										 |  |  | MyTcpClient* MyTcpClient::instance() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_instance) { | 
					
						
							|  |  |  |         m_instance = new MyTcpClient(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return m_instance; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-03-13 15:12:03 +08:00
										 |  |  | 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() { | 
					
						
							| 
									
										
										
										
											2025-05-14 23:14:50 +08:00
										 |  |  |     m_buffer.append(socket->readAll()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (true) { | 
					
						
							|  |  |  |        if (m_buffer.size() < sizeof(BaseHeader)) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        const BaseHeader *base = reinterpret_cast<const BaseHeader *>(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<const LargeHeaderExtra *>( | 
					
						
							|  |  |  |                m_buffer.constData() + sizeof(BaseHeader)); | 
					
						
							|  |  |  |            int payloadLen = extra->len; | 
					
						
							| 
									
										
										
										
											2025-05-15 18:09:43 +08:00
										 |  |  |            if (payloadLen <= 0 || payloadLen > 10 * 1024 * 1024) { | 
					
						
							| 
									
										
										
										
											2025-05-14 23:14:50 +08:00
										 |  |  |                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; // 等待完整数据到达
 | 
					
						
							| 
									
										
										
										
											2025-05-15 18:09:43 +08:00
										 |  |  |            emit dataReceived( m_buffer); | 
					
						
							|  |  |  |            m_buffer.remove(0, totalLen); | 
					
						
							|  |  |  |        }else if(cmd == kGetLogInfo){ | 
					
						
							|  |  |  |            if (m_buffer.size() < sizeof(GetSubCardLogRsp)) | 
					
						
							|  |  |  |                return; // 等待更多数据
 | 
					
						
							| 
									
										
										
										
											2025-05-14 23:14:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-15 18:09:43 +08:00
										 |  |  |            const GetSubCardLogRsp *extra = reinterpret_cast<const GetSubCardLogRsp *>(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; // 等待完整数据到达
 | 
					
						
							| 
									
										
										
										
											2025-05-14 23:14:50 +08:00
										 |  |  |            emit dataReceived( m_buffer); | 
					
						
							|  |  |  |            m_buffer.remove(0, totalLen); | 
					
						
							|  |  |  |        } else { | 
					
						
							|  |  |  |            QByteArray fullData = m_buffer; | 
					
						
							|  |  |  |            emit dataReceived(fullData); | 
					
						
							|  |  |  |            m_buffer.clear(); | 
					
						
							|  |  |  |            return; // 等待下一批数据
 | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2025-03-13 15:12:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |