#pragma execution_character_set("utf-8") #include "netControl.h" #include "commonDefine.h" #include NetControl::NetControl(const QString& configPath, bool bAutoReconnect /* = false */, QObject *parent /* = 0 */) : QObject(parent), m_bAutoReconnect(bAutoReconnect), m_configPath(configPath) { qRegisterMetaType("QAbstractSocket::SocketError"); initIpAddress(m_configPath); } NetControl::~NetControl() { qDebug() << "delete netControl"; if (m_pTimerHeartbeat) { m_pTimerHeartbeat->stop(); m_pTimerHeartbeat->deleteLater(); m_pTimerHeartbeat = nullptr; } if (m_pTcpSocket) { m_pTcpSocket->abort(); m_pTcpSocket->close(); m_pTcpSocket->deleteLater(); m_pTcpSocket = nullptr; } qDebug() << "delete netControl finished"; } bool NetControl::initIpAddress(const QString& path) { QFile file(path); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "打开文件失败!"; return false; } QByteArray arr = file.readAll(); file.close(); if (arr.isEmpty()) { qWarning() << "内容为空"; return false; } QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(arr, &err); if (doc.isEmpty()) { qWarning() << err.errorString(); //打印失败信息 return false; } QJsonObject docObj = doc.object(); QJsonObject TcpNetObj = docObj.value("TcpNetWork").toObject(); if (!TcpNetObj.isEmpty()) { m_szHostIp = TcpNetObj.value("Host_IP").toString(); m_port = TcpNetObj.value("Host_Port").toInt(); m_streetName = TcpNetObj.value("Street_Name").toString(); if (TcpNetObj.contains("Heart_Interval")) { m_heartInterval = TcpNetObj.value("Heart_Interval").toInt(); } } return true; } Q_SLOT void NetControl::onInitNet() { m_pTimerHeartbeat = new QTimer(this); connect(m_pTimerHeartbeat, &QTimer::timeout, this, &NetControl::sendHeartbeatPack); m_pTcpSocket = new QTcpSocket(this); connect(m_pTcpSocket, SIGNAL(connected()), this, SLOT(onConnected())); connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onErrorHandler(QAbstractSocket::SocketError))); connect(m_pTcpSocket, SIGNAL(readyRead()), this, SLOT(onMsgReceived())); connect(m_pTcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnected())); connectNet(m_szHostIp, m_port); } void NetControl::connectNet(QString severIp, int serverPort) { m_pTcpSocket->connectToHost(severIp, serverPort); } void NetControl::onErrorHandler(QAbstractSocket::SocketError err) { QMetaEnum metaEnum = QMetaEnum::fromType(); switch (err) { case QAbstractSocket::AddressInUseError: qCritical() << __FUNCTION__ <<": "<< metaEnum.key(err) << endl << "SOCKET ERROR: Address is already in use"; break; case QAbstractSocket::ConnectionRefusedError: qWarning() << __FUNCTION__ << ": " << metaEnum.key(err) << endl << "SOCKET ERROR: Connection refused"; m_pTcpSocket->abort(); m_pTcpSocket->close(); if (m_bAutoReconnect) { qDebug() << __FUNCTION__ << ": " << metaEnum.key(err) << endl << "Reconnecting ..."; QThread::sleep(1); m_pTcpSocket->connectToHost(m_szHostIp, m_port); } break; case QAbstractSocket::HostNotFoundError: { qCritical() << __FUNCTION__ << ": " << metaEnum.key(err) << endl << "SOCKET ERROR: Host not found"; qDebug() << "连接失败,未找到对应地址"; } break; case QAbstractSocket::RemoteHostClosedError: qCritical() << __FUNCTION__ << ": " << metaEnum.key(err) << endl << "SOCKET ERROR: Remote host closed"; break; default: { // 网络波动可能导致断开链接后的重连失败,报错NetworkError qCritical() << __FUNCTION__ << ": " << metaEnum.key(err) << endl; if (!m_pTcpSocket->isOpen() && m_bAutoReconnect) { qDebug() << __FUNCTION__ << ": Start to reconnect ..."; QThread::sleep(1); m_pTcpSocket->connectToHost(m_szHostIp, m_port); } break; } } } void NetControl::onConnected() { qDebug() << __FUNCTION__ << endl << "TPTcpClient::slotConnected"; QString strSend = CREATE_CONNECT_HEAD; strSend = strSend + SPLIT_RULE + m_streetName + END_SYMBOL; QByteArray basend; basend.append(strSend); m_pTcpSocket->write(basend.constData(), basend.size()); if (!m_pTimerHeartbeat) { m_pTimerHeartbeat = new QTimer(this); } m_pTimerHeartbeat->start(m_heartInterval * 1000); qDebug() << "网络连接成功!!!"; } void NetControl::onDisconnected() { qDebug() << __FUNCTION__ << endl << "TPTcpClient::slotDisconnected"; m_pTimerHeartbeat->stop(); m_pTcpSocket->abort(); m_pTcpSocket->close(); QThread::sleep(1); qDebug() << "网络已断开连接!!!"; //ready for auto connect and re-connect if (m_bAutoReconnect) { m_pTcpSocket->connectToHost(m_szHostIp, m_port); } } void NetControl::onMsgReceived() { QByteArray datain = m_pTcpSocket->readAll(); QString msg = datain; if (!QString::compare(msg, CREATE_CONNECT_HEAD)) { qDebug() << "connected"; return; } if (msg.startsWith(HEARTBEAT_HEAD)) { return; } else { qWarning() << "i receive data from server:" << msg; emit sgReceiveData(msg); } } void NetControl::sendHeartbeatPack() { if (m_pTcpSocket->state() != QAbstractSocket::SocketState::ConnectedState) return; QString strSend = HEARTBEAT_HEAD; strSend = strSend + SPLIT_RULE + m_streetName + END_SYMBOL; QByteArray basend; basend.append(strSend); m_pTcpSocket->write(basend.constData(), basend.size()); } void NetControl::waitForConnected(int msec) { bool ok = m_pTcpSocket->waitForConnected(msec); if (!ok) { qDebug() << "网络未连接,请重试"; } } Q_SLOT void NetControl::onSendMsg(const QString& msg) { if (m_pTcpSocket->state() != QAbstractSocket::SocketState::ConnectedState) { qDebug() << "网络未连接"; return; } QByteArray msgBytArr; msgBytArr.append(msg); m_pTcpSocket->write(msgBytArr); }