You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
smokeboxidentification/src/NetControl.cpp

225 lines
5.6 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma execution_character_set("utf-8")
#include "netControl.h"
#include "commonDefine.h"
#include <QMetaEnum>
NetControl::NetControl(const QString& configPath, bool bAutoReconnect /* = false */, QObject *parent /* = 0 */)
: QObject(parent),
m_bAutoReconnect(bAutoReconnect), m_configPath(configPath)
{
qRegisterMetaType<QAbstractSocket::SocketError>("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<QAbstractSocket::SocketError>();
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);
}