#include "Hd_SocketModule_TCP.h" #include "qcoreapplication.h" //读到的信息列表 QQueue< QByteArray> readDataList; QByteArray readResult = ""; QMutex* r_Mutex = new QMutex(); QMutex* write_Mutex = new QMutex(); QMutex* read_Mutex = new QMutex(); QMutex* recive_Mutex = new QMutex(); bool connectStatus = true; Hd_SocketModule_TCP* create() { qDebug() << "[INFO] " << "Hd_SocketModule_TCP create success!"; return new Hd_SocketModule_TCP; } void destory(Hd_SocketModule_TCP* ptr) { if (ptr) { delete ptr; ptr = nullptr; } qDebug() << "[INFO] " << " Hd_SocketModule_TCP destory success!"; } Hd_SocketModule_TCP::Hd_SocketModule_TCP() { read_Mutex = new QMutex; recive_Mutex = new QMutex(); m_Thread = new MyThread(this); m_Thread->setMutexLock(read_Mutex); } Hd_SocketModule_TCP::~Hd_SocketModule_TCP() { m_Thread->setRunStop(); m_Thread->wait(); m_Thread->quit(); if (m_Thread) { qDebug() << "[INFO] " << "~m_Thread()"; delete m_Thread; m_Thread = nullptr; } qDebug() << "[INFO] " << "~Hd_SocketModule_TCP success!"; } //从类中读数据到实例对象 bool Hd_SocketModule_TCP::readData(std::vector& vec_mat, QByteArray& data) { Q_UNUSED(vec_mat); /*if (ReadPack.isEmpty()) return true;*/ // 发送数据包 /*QMutexLocker locker(read_Mutex); QByteArray m_byte = ReadPack.dequeue();*/ QByteArray m_byte = ""; int times = 0; while (m_byte == "") { //读超时,退出 times++; if (times > 100) { //qDebug() << "[TCP] " << "fansTcp readCmd fail"; return false; } read_Mutex->lock(); if(readDataList.size()>0) m_byte = readDataList.dequeue(); read_Mutex->unlock(); Sleep(5); } /*m_byte.remove(0, 30);*/ data = m_byte; //qDebug() << __FUNCTION__ << "line:" << __LINE__ << "result:" << data.size(); return true; } //实例对象把数据写入到类 bool Hd_SocketModule_TCP::writeData(std::vector& vec_mat, QByteArray& data) { Q_UNUSED(vec_mat); recive_Mutex->lock(); if (data.isEmpty()) { qCritical() << "[Hd_SocketModule_TCP] " << " str is null"; recive_Mutex->unlock(); return false; } QList m_list = data.split('_'); QString commond = m_list.at(0); if (commond == "init") { m_host = m_list.at(1); m_pot = m_list.at(2); if (!m_Thread->setIpAndPort(m_host, m_pot)) { qDebug() << "[Hd_SocketModule_TCP] " << "m_IP:" << m_host << " m_host:" << m_pot << " connectToHost failed!"; recive_Mutex->unlock(); return false; } } else { m_Thread->WritePLCPack.enqueue(data); } recive_Mutex->unlock(); return true; } //初始化 bool Hd_SocketModule_TCP::initParas(QByteArray& data) { qDebug() << "[Hd_SocketModule_TCP] " << "DATA: " << data; if (data.isEmpty()) { qCritical() << "[Hd_SocketModule_TCP] " << " str is null"; recive_Mutex->unlock(); return false; } QList m_list = data.split('_'); QString commond = m_list.at(0); if (commond == "init") { m_host = m_list.at(1); m_pot = m_list.at(2); if (!m_Thread->setIpAndPort(m_host, m_pot)) { qDebug() << "[Hd_SocketModule_TCP] " << "m_IP:" << m_host << " m_host:" << m_pot << " connectToHost failed!"; return false; } } m_Thread->start(); Sleep(500); if (!m_Thread->getInitSuccessFlag()) { qCritical() << "[Hd_SocketModule_TCP] " << "TCP init failed!"; return false; } // 开启线程循环 m_Thread->start(); return true; } bool Hd_SocketModule_TCP::run() { //qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!"; if (connectStatus == false) connectStatus = true; return connectStatus; } //检查异常标志 bool Hd_SocketModule_TCP::checkStatus() { read_Mutex->lock(); bool connectStatus1 = connectStatus; read_Mutex->unlock(); return connectStatus1; } MyThread::~MyThread() { if (tcpsocket) { tcpsocket->deleteLater(); } // tcp通信的socket if (m_mutex_lock) { delete m_mutex_lock; m_mutex_lock = nullptr; } } void MyThread::closeSocket() { if (tcpsocket) { tcpsocket->abort(); tcpsocket->disconnect(); tcpsocket->close(); } qDebug() << "[Hd_SocketModule_TCP] " << " Hd_SocketModule_FinsTcp close tcpsocket success!"; } //断线重连函数 bool MyThread::disReconnects() { bool reResult = false; if (!(tcpsocket->state() == QAbstractSocket::ConnectedState)) { read_Mutex->lock(); connectStatus = false; read_Mutex->unlock(); qCritical() << "[Hd_SocketModule_TCP] " << QString("tcp disconected"); //QMessageBox::information(MyThreadWidget,"连接断开", "Hd_SocketModule_TCP连接断开,开始自动重连"); while(1) { if (init_flag == 2)break; tcpsocket->bind(QHostAddress::Any); tcpsocket->connectToHost(m_IP, m_Port.toInt()); if (tcpsocket->waitForConnected(5)) { qWarning() << "[Hd_SocketModule_TCP] " << " You have connected to the server again"; //QMessageBox::information(MyThreadWidget, "自动重连", "Hd_SocketModule_TCP自动重连成功"); reResult = true; read_Mutex->lock(); connectStatus = true; read_Mutex->unlock(); break; } Sleep(200); qApp->processEvents(); } } else reResult = true; return reResult; } //线程 run 中初始化 socket void MyThread::run() { qDebug() << "[TCP] " << " run start"; if (init_flag == 0) { tcpsocket = new QTcpSocket(this); tcpsocket->bind(QHostAddress::Any); tcpsocket->abort(); if (tcpsocket->state() == QAbstractSocket::ConnectedState) { qCritical() << "[Hd_SocketModule_TCP] " << QString("[%1:%2] server has been linked").arg(m_IP).arg(m_Port); return; } tcpsocket->connectToHost(m_IP, m_Port.toInt()); if (tcpsocket->waitForConnected(5)) { qWarning() << "[Hd_SocketModule_TCP] " << " You have connected to the server "; connectStatus = true; } else { qWarning() << "[Hd_SocketModule_TCP] " << " Hd_SocketModule_TCP :: Server not connected"; init_success = false; read_Mutex->lock(); connectStatus = false; read_Mutex->unlock(); return; } init_flag = 1; qDebug() << "[Hd_SocketModule_TCP] " << " run end ----------"; } else if (init_flag == 1) { //开启wile循环来读写 while (true) { if (init_flag == 2) { break; } writeSocketData(); qApp->processEvents(); Sleep(20); readSocketData(); qApp->processEvents(); Sleep(20); } } if (init_flag == 2) { QThread::msleep(10); closeSocket(); } } bool MyThread::setIpAndPort(QString ip, QString port) { m_IP = ip; m_Port = port; return true; } //读取数据 void MyThread::readSocketData() { qApp->processEvents(); QByteArray readData = tcpsocket->readAll(); if (readData.isEmpty()) return; read_Mutex->lock(); readDataList.append(readData); read_Mutex->unlock(); readData.clear(); Sleep(5); } //往PLC发报文 void MyThread::writeSocketData() { if (WritePLCPack.isEmpty()) return; //写PLC if (!WritePLCPack.isEmpty()) { for (int i = 0; i < WritePLCPack.size(); i++) { recive_Mutex->lock(); if (!(WritePLCPack.size() > 0)) { recive_Mutex->unlock(); break; } QByteArray byte = WritePLCPack.dequeue(); // 取出包 recive_Mutex->unlock(); if (!disReconnects()) { qDebug() << "[Hd_SocketModule_TCP] " << QString("The server cannot be connected. Check the network port"); //init_flag = 2; return; } tcpsocket->write(byte); tcpsocket->waitForBytesWritten(3000); tcpsocket->flush(); qApp->processEvents(); } } return; }