#include "Hd_SocketModule_ModbusTcp.h" #include "qcoreapplication.h" bool connectStatus = true; struct PLCPack { QString address; QString type; QVector value; QString num; }; static QQueue WritePLCPack; //static QQueue ReadPack; static QQueue ReadPLCPack; bool* v_bool = nullptr; short* v_short = nullptr; unsigned char* v_byte = nullptr; int* v_int = nullptr; long long* v_longlong = nullptr; float* v_float = nullptr; unsigned short* v_ushort = nullptr; unsigned int* v_uint = nullptr; unsigned long long* v_ulonglong = nullptr; double* v_double = nullptr; char* v_char = nullptr; QByteArray readResult = ""; QMutex* r_Mutex = new QMutex(); QMutex* write_Mutex = new QMutex(); QMutex* read_Mutex = new QMutex(); QMutex* recive_Mutex = new QMutex(); Hd_SocketModule_ModbusTcp* create() { qDebug() << "[INFO] " << "Hd_SocketModule_ModbusTcp create success!"; return new Hd_SocketModule_ModbusTcp; } void destory(Hd_SocketModule_ModbusTcp* ptr) { if (ptr) { delete ptr; ptr = nullptr; } qDebug() << "[INFO] " << " Hd_SocketModule_ModbusTcp destory success!"; } // 可传递ushort 类型的值 和-1 QString Hd_SocketModule_ModbusTcp::UShortToHex(int num) { if (num == -1) { return "FF FF"; } QString result = QString::number(num, 16); if (result.size() == 1) { result = "00 0" + result; } if (result.size() == 2) { result = "00 " + result; } if (result.size() == 3) { result = "0" + result; result.insert(2, " "); } if (result.size() == 4) { result.insert(2, " "); } return result; } // 可传递short类型的正负值 QString Hd_SocketModule_ModbusTcp::ShortToHex(int value) { QString result = QString::number(value, 16); result = result.right(4); if (result.size() == 1) { result = "000" + result; } if (result.size() == 2) { result = "00" + result; } if (result.size() == 3) { result = "0" + result; } QString m_data1 = result.mid(0, 2); QString m_data2 = result.mid(2, 2); result = m_data1 + " " + m_data2; return result; } Hd_SocketModule_ModbusTcp::Hd_SocketModule_ModbusTcp() { m_Mutex = new QMutex; //m_Thread = new MyThread(this); m_Thread.setMutexLock(m_Mutex); } Hd_SocketModule_ModbusTcp::~Hd_SocketModule_ModbusTcp() { m_Thread.setRunStop(); m_Thread.wait(); m_Thread.quit(); m_Thread.terminate(); //if (m_Thread) //{ // qDebug() << "[INFO] "<< "~m_Thread()"; // delete m_Thread; // m_Thread = nullptr; //} qDebug() << "[INFO] " << "~Hd_SocketModule_ModbusTcp success!"; } bool Hd_SocketModule_ModbusTcp::readData(std::vector& vec_mat, QByteArray& data) { Q_UNUSED(vec_mat); /*if (ReadPack.isEmpty()) return true;*/ // 发送数据包 /*QMutexLocker locker(m_Mutex); QByteArray m_byte = ReadPack.dequeue();*/ QByteArray m_byte = ""; int times = 0; while (m_byte == "") { times++; if (times > 2000) { qDebug() << "[TCP] " << "ModbusTcp readCmd fail"; return false; } r_Mutex->lock(); m_byte = readResult; if (m_byte != "") readResult = ""; r_Mutex->unlock(); Sleep(5); } /*m_byte.remove(0, 30);*/ data = m_byte; //qDebug() << __FUNCTION__ << "line:" << __LINE__ << "result:" << data.size(); return true; } //接收数据 bool Hd_SocketModule_ModbusTcp::writeData(std::vector& vec_mat, QByteArray& data) { Q_UNUSED(vec_mat); recive_Mutex->lock(); QString str = QString(data); if (data.isEmpty()) { qCritical() << "[TCP] " << " str is null"; recive_Mutex->unlock(); return false; } std::string rev = data.toStdString(); //std::cout << "rev:" << rev < m_list = data.split('_'); QString m_value; QString m_ip_lastpos; QString m_type; QString commond = m_list.at(0); if (commond == "init") { m_IP = m_list.at(1); m_host = m_list.at(2); m_Station = m_list.at(3); QStringList list = m_IP.split("."); if (list.size() == 4) { m_ip_lastpos = list.at(3); } std::cout << "init IP:" << m_IP.toStdString() << " Host:" << m_host.toStdString() << " Sta:" << m_Station.toStdString() << endl; if (!m_ip_lastpos.isEmpty()) { if (m_ip_lastpos.toInt() < 10) { hex_ip_lastpos = "0" + m_ip_lastpos; } else { hex_ip_lastpos = QString::number(m_ip_lastpos.toInt(), 16); } } else { qCritical() << "[TCP] " << " m_ip_lastpos is null! "; recive_Mutex->unlock(); return false; } } else { //for (auto data : m_list) // std::cout << data.toInt() << endl; m_type = m_list.at(1); //数据类型 //m_posName = m_list.at(2); m_pos = m_list.at(2); //m_pos = m_pos.split("DM")[1]; // 获取点位 m_value = m_list.at(3); //std::string m_valueStr = m_value.toStdString(); if (m_pos.isEmpty() || m_value.isEmpty()) { qCritical() << "[TCP] " << "decode Commond null!"; recive_Mutex->unlock(); return false; } } //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " m_posName:" << m_posName << " m_pos:" << m_pos << " m_value:" << m_value; if (commond.isEmpty()) { qCritical() << "[TCP] " << "decode Commond null!"; recive_Mutex->unlock(); return false; } if (commond == "init") { } else if (commond == "writeHeart") { QVector vec_value; QString vecValue = m_value; QStringList valueList = vecValue.split(","); for (size_t i = 0; i < valueList.size(); i++) { vec_value.push_back(valueList[i]); } writeCommond(m_pos, m_type, vec_value); } else if (commond == "write") { QVector vec_value; QString vecValue = m_value; QStringList valueList = vecValue.split(","); for (size_t i = 0; i < valueList.size(); i++) { vec_value.push_back(valueList[i]); } writeCommond(m_pos, m_type, vec_value); qDebug() << "[TCP] " << str << endl; } else if (commond == "read") { //设置延迟时间 Sleep(m_sleepTime); readCommond(m_pos, m_type, m_value);//地址,类型,个数 } //else if (commond == "readAll") //{ // //设置延迟时间 // //Sleep(m_sleepTime); // readAllCommond(m_pos, m_value); //} //else if (commond == "writeAll") // 格式 writeAll_DM100_3_101 // 起始位置+数量+值 //{ // QVector vec_value; // QString vecValue = m_list.at(3); // QStringList valueList = vecValue.split(","); // for (size_t i = 0; i < valueList.size(); i++) // { // bool valid = false; // short v = valueList[i].toShort(&valid); // if(valid)vec_value.push_back(v); // } // writeAllCommond(m_pos, m_value, vec_value); //m_value 为数量 // qDebug() << "[TCP] " << str << endl; //} //else if (commond == "writeString") //{ // QString vecValue = m_list.at(3); // writeStringCommond(m_pos, m_value, vecValue); // qDebug() << "[TCP] " << str << endl; //} //else if (commond == "writeResult") //{ // QVector vec_value; // QByteArray vecByte = m_list.at(3); // qDebug() << "[TCP] " << str << endl; // if (!decodeWriteResult(vecByte, vec_value)) // { // qCritical() << "[TCP] " << " decodeWriteResult is error!"; // recive_Mutex->unlock(); // return false; // } // if (!writeResultCommond(m_pos, m_value, vec_value)) // { // recive_Mutex->unlock(); // return false; // } // //qDebug() << __FUNCTION__ << " line:" << __LINE__ << " ----<>----- vec_value:" << vec_value; //} recive_Mutex->unlock(); return true; } //解析要往PLC写的数据;不同的通信协议,可能不一样 bool Hd_SocketModule_ModbusTcp::decodeWriteResult(QByteArray byte, QVector& vec_ret) { try { if (byte.isEmpty()) { qCritical() << "[TCP] " << " byte is null!"; return false; } while (!byte.isEmpty()) { int len = 0; QByteArray m_len = byte.mid(0, 4); memcpy((void*)&len, (void*)m_len.data(), 4); // qDebug() << __FUNCTION__ << " line:" << __LINE__ << " len:" << len; byte.remove(0, 4); QByteArray mm_data = byte.mid(0, len); // qDebug() << __FUNCTION__ << " line:" << __LINE__ << " mm_data:" << mm_data; vec_ret.append(QString::fromUtf8(mm_data)); byte.remove(0, len); } } catch (QString ev) { qCritical() << "[Error] " << " ev:" << ev; return false; } return true; } bool Hd_SocketModule_ModbusTcp::tcpServer(QByteArray cmd, QByteArray& m_resultPack) { return false; } void Hd_SocketModule_ModbusTcp::decodePack(QByteArray resultArray) { } //初始化 bool Hd_SocketModule_ModbusTcp::initParas(QByteArray& data) { qDebug() << "[TCP] " << "DATA: " << data; if (data.isEmpty()) { qWarning()<< "[TCP] " << " data is null!"; } else { QString initDat = QString::fromUtf8(data); QStringList list = initDat.split("_"); if (list.size() < 3) { qCritical() << "[TCP] " << " list size error :" << list.size(); return false; } QString sleepname = list.at(0); QString sleepvalue = list.at(1); QString readname = list.at(2); QString readvalue = list.at(3); QString write_type = list.at(4); QString write_value = list.at(5); std::cout << "sleepname:" << sleepname.toStdString() << " sleepvalue:" << sleepvalue.toStdString() << " readname:" << readname.toStdString() << " readvalue:" << readvalue.toStdString() << " write_type:" << write_type.toStdString() << " write_value:" << write_value.toStdString() <<" m_host:"<< m_host.toStdString() << endl; // 设置收发数据的类型 if (!write_value.isEmpty()) m_writeType = write_value; qDebug() << "[TCP] " << "list: " << list; setSleepTimeAndReadNum(sleepvalue.toInt(), readvalue.toInt()); m_Thread.setSocketIp(m_Station); if (!m_Thread.setIpAndPort(m_IP, m_host)) { qDebug() << "[TCP] " << "m_IP:" << m_IP << " m_host:" << m_host << " connectToHost failed!"; return false; } } //开启读PLC数据的客户端 //开启socket //第一次运行,创建socket对象,后面发一次握手报文 m_Thread.start(); int cnt = 0; while (!m_Thread.getInitSuccessFlag()) { QThread::msleep(100); cnt++; if(cnt>50) { qCritical() << "[TCP] " << "TCP init failed!"; return false; } } //// 发送握手指令 //QString ret = "46 49 4E 53 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 " + socketIp; //QByteArray array = QByteArray::fromHex(ret.toLatin1()); //使用16进制格式 //WritePLCPack.append(array); // 开启线程循环 m_Thread.start(); return true; } bool Hd_SocketModule_ModbusTcp::run() { //qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!"; return true; } //通信偷懒时间 void Hd_SocketModule_ModbusTcp::setSleepTimeAndReadNum(int time, int num) { m_sleepTime = time; m_Thread.setReadPackValue(num); } ////写单个寄存器指令,封装为报文 //bool Hd_SocketModule_ModbusTcp::writeCommond(QString DM, QString Num) //{ // try // { // if (DM.isEmpty() || Num.isEmpty()) // { // qCritical() << "[TCP] " << " DM or Num is null!"; // return false; // } // // PLCPack temp; // temp.type = "short"; // temp.num = "1"; // temp.value = Num; // temp.address = DM; // // //int mm_pos = DM.toInt(); // //int mm_value = Num.toInt(); // //mm_pos = abs(mm_pos); // //// mm_value = abs(mm_value); // //DM = UShortToHex(mm_pos); // //Num = UShortToHex(mm_value); // //QString ret = "46 49 4E 53 00 00 00 1C 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 "+ socketIp +" 00 00 01 02 82 " + DM + "00 00 01 " + Num; // //QByteArray array = QByteArray::fromHex(ret.toLatin1()); // 使用 16 进制格式 // write_Mutex->lock(); // //if(!WritePLCPack.contains(temp)) // WritePLCPack.enqueue(temp); // write_Mutex->unlock(); // } // catch (QString ev) // { // qDebug() << "[TCP] " << "writeCommond failed!" << Num; // } // return true; //} // //// 备注:不能写入 -1 //// 写入起始地址 + 写入数量 + 写入的值;批量写,通信时间比写单个寄存器稍长; //bool Hd_SocketModule_ModbusTcp::writeAllCommond(QString DM, QString write_Num, QVector vec_value) //{ // try // { // if (DM.isEmpty() || write_Num.isEmpty()) // { // qCritical() << "[TCP] " << " DM or Num is null!"; // return false; // } // // PLCPack temp; // temp.type = "shorts"; // temp.num = QString::number(vec_value.size()); // QString value = ""; // for (int i = 0; i < vec_value.size(); i++) // { // short v = (short)vec_value[i]; // if (i == vec_value.size() - 1) // { // value = value + QString::number(v); // } // else // { // value = value + QString::number(v) + ","; // } // // } // temp.value = value; // temp.address = DM; // // write_Mutex->lock(); // //if (!WritePLCPack.contains(temp)) // WritePLCPack.enqueue(temp); // write_Mutex->unlock(); // // //int m_len = 26 + vec_value.size() * 2; // //int mm_pos = DM.toInt(); // //int mm_Num = write_Num.toInt(); // //mm_pos = abs(mm_pos); // //mm_Num = abs(mm_Num); // //DM = UShortToHex(mm_pos); // 位置 // //write_Num = UShortToHex(mm_Num); // 写入数量 // //QString string_len = UShortToHex(m_len); // //qDebug() << "[TCP] " << " write_Num:" << write_Num; // //QString write_data = "46 49 4E 53 00 00 " + string_len + " 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 "+ socketIp+" 00 00 01 02 82 " + DM + " 00 " + write_Num; // // //// 写入值拼凑 // //QString send_value; // //for (int i = 0; i < vec_value.size(); i++) // //{ // // int value = abs(vec_value.at(i)); // // send_value += " " + UShortToHex(value); // 写入的每一位的值 // //} // //write_data += send_value; // //qDebug() << "[TCP] " << " write_data:" << write_data; // //QByteArray array = QByteArray::fromHex(write_data.toLatin1()); // 使用 16 进制格式 // //write_Mutex->lock(); // //WritePLCPack.append(array); // //write_Mutex->unlock(); // } // catch (QString ev) // { // qDebug() << "[TCP] " << "writeCommond failed!" << write_Num; // return false; // } // return true; //} ////写入起始地址 + 写入数量 + 写入的值 //bool Hd_SocketModule_ModbusTcp::writeResultCommond(QString DM, QString write_Num, QVector vec_value) //{ // try // { // if (vec_value.isEmpty()) // { // qCritical() << "[TCP] " << " vec_value is null!"; // return false; // } // // PLCPack temp; // temp.type = "strings"; // temp.num = QString::number(vec_value.size()); // QString value = ""; // for (int i = 0; i < vec_value.size(); i++) // { // QString v = vec_value[i]; // if (i == vec_value.size() - 1) // { // value = value + v; // } // else // { // value = value + v + ","; // } // // } // temp.value = value; // temp.address = DM; // // write_Mutex->lock(); // //if (!WritePLCPack.contains(temp)) // WritePLCPack.enqueue(temp); // write_Mutex->unlock(); // // /*PLCPack temp; // temp.Command = "write"; // temp.type = "string"; // temp.num = "1"; // temp.value = Num; // temp.address = "D" + DM;*/ // // //int m_len = 26 + vec_value.size() * 2; // //int mm_pos = DM.toInt(); // 起始位 // //int mm_Num = write_Num.toInt(); // 写入数量 // //mm_pos = abs(mm_pos); // //mm_Num = abs(mm_Num); // //DM = UShortToHex(mm_pos); // 位置 // //write_Num = UShortToHex(mm_Num); // 写入数量 // //QString string_len = UShortToHex(m_len); // // //QString write_data = "46 49 4E 53 00 00 " + string_len + " 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 " + socketIp + " 00 00 01 02 82 " + DM + " 00 " + write_Num; // // //qDebug() << "[TCP] " << " m_writeType:" << m_writeType << " write_data:" << write_data; // // ////写入值拼凑 // //QString send_value; // //for (int i = 0; i < vec_value.size(); i++) // //{ // // int value = vec_value.at(i).toInt(); // // //根据发的类型来判断 // // if (m_writeType == "short") // // { // // send_value += " " + ShortToHex(value); // 写入的每一位的值 // // } // // else // // { // // send_value += " " + UShortToHex(value); // 写入的每一位的值 // // } // //} // // //write_data += send_value; // //QByteArray m_byte = QByteArray::fromHex(write_data.toLatin1()); // 使用 16 进制格式 // //QString str; // //for (int i = 0; i < m_byte.size(); i++) // //{ // // str += QString("%1").arg((unsigned char)m_byte.at(i), 2, 16, QLatin1Char('0')) + ' '; // //} // //qDebug() << "[TCP] " << " writeData str:" << str; // //write_Mutex->lock(); // //WritePLCPack.append(m_byte); // //write_Mutex->unlock(); // } // catch (QString ev) { // qCritical() << "[TCP] " << " writeCommond failed!" << write_Num; // return false; // } // return true; //} ////写字符串 //bool Hd_SocketModule_ModbusTcp::writeStringCommond(QString DM, QString write_num, QString vec_value) //{ // try // { // if (DM.isEmpty()) // { // qCritical() << "[TCP] " << " DM or Num is null!"; // return false; // } // // PLCPack temp; // temp.type = "string"; // temp.num = "1"; // temp.value = vec_value; // temp.address = DM; // // write_Mutex->lock(); // //if (!WritePLCPack.contains(temp)) // WritePLCPack.append(temp); // write_Mutex->unlock(); // // //int m_len = 26 + vec_value.size(); // // //int mm_pos = DM.toInt(); // //int mm_Num; // //mm_pos = abs(mm_pos); // //mm_Num = abs(write_num.toInt()); // //DM = UShortToHex(mm_pos); //位置 // //QString write_Num = UShortToHex(mm_Num); //写入数量 // //QString string_len = UShortToHex(m_len); // //qDebug() << "[TCP] " << " write_Num:" << write_Num; // // //QString write_data = "46 49 4E 53 00 00 " + string_len + " 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 " + socketIp + " 00 00 01 02 82 " + DM + " 00 " + write_Num; // // ////写入值拼凑 // //QByteArray strArray; // //if (vec_value.size() == 1) // //{ // // strArray = "00 " + vec_value.toUtf8().toHex().toUpper(); // //} // //else // //{ // // if (vec_value.size() % 2 == 0) // // { // // for (int i = 0; i < vec_value.size(); i++) // // { // // QByteArray strArray1; // // strArray1 = QString(vec_value.at(i)).toUtf8().toHex().toUpper(); // // if (i == vec_value.size() - 1) // // strArray = strArray + strArray1; // // else // // strArray = strArray + strArray1 + " "; // // } // // } // // else // // { // // for (int i = 0; i < vec_value.size(); i++) // // { // // QByteArray strArray1; // // strArray1 = QString(vec_value.at(i)).toUtf8().toHex().toUpper(); // // if (i == vec_value.size() - 1) // // { // // strArray = strArray + "00 " + strArray1; // // // } // // else // // { // // strArray = strArray + strArray1 + " "; // // } // // } // // } // //} // // // //write_data = write_data + " " + strArray; // // //qDebug() << "[TCP] " << " write_data:" << write_data; // //QByteArray array = QByteArray::fromHex(write_data.toLatin1()); // 使用 16 进制格式 // // //write_Mutex->lock(); // //WritePLCPack.append(array); // //write_Mutex->unlock(); // // } // catch (QString ev) // { // qDebug() << "[TCP] " << "writeCommond failed!"; // return false; // } // return true; //} ////读寄存器 //bool Hd_SocketModule_ModbusTcp::readCommond(QString DM, QString Num) //{ // try // { // if (DM.isEmpty() || Num.isEmpty()) // { // qCritical() << "[TCP] " << " DM or Num is null!"; // return false; // } // // PLCPack temp; // temp.type = "short"; // temp.num = Num; // temp.value = ""; // temp.address = DM; // // read_Mutex->lock(); // ReadPLCPack.enqueue(temp); // read_Mutex->unlock(); // //int mm_pos = DM.toInt(); // //int mm_value = Num.toInt(); // //DM = UShortToHex(mm_pos); // //Num = UShortToHex(mm_value); // //QString ret = "46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 " + socketIp + " 00 00 01 01 82 " + DM + " 00 " + Num; // //QByteArray array = QByteArray::fromHex(ret.toLatin1()); // 使用16 进制格式 // ////WritePack.append(array); // ///*QByteArray resultArray; // //bool isConed = tcpServer(array, resultArray); // //decodePack(resultArray);*/ // //bool ifHas = false; // //for (int i = 0; i < ReadPLCPack.size(); i++) // //{ // // if (ReadPLCPack[i] == array)ifHas = true; // //} // //if (ifHas == false) // //{ // // read_Mutex->lock(); // // ReadPLCPack.append(array); // // read_Mutex->unlock(); // //} // } // catch (QString ev) // { // qDebug() << "[TCP] " << "readCommond failed!" << Num; // } // return true; //} ////批量读寄存器 //bool Hd_SocketModule_ModbusTcp::readAllCommond(QString DM, QString Num) //{ // try // { // if (DM.isEmpty() || Num.isEmpty()) // { // qCritical() << "[TCP] " << " DM or Num is null!"; // return false; // } // // // PLCPack temp; // temp.type = "bytes"; // temp.num = Num; // temp.value = ""; // temp.address = DM; // // read_Mutex->lock(); // ReadPLCPack.enqueue(temp); // read_Mutex->unlock(); // // int mm_pos = DM.toInt(); // // int mm_value = Num.toInt(); // // // DM = UShortToHex(mm_pos); // // Num = UShortToHex(mm_value); // // QString ret = "46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 " + socketIp + " 00 00 01 01 82 " + DM + " 00 " + Num; // // QByteArray array = QByteArray::fromHex(ret.toLatin1()); // 使用16 进制格式 // // //WritePack.append(array); // // /*QByteArray resultArray; // // bool isConed = tcpServer(array, resultArray); // // decodePack(resultArray);*/ // // ///* bool ifHas = false; // // for (int i = 0; i < ReadPLCPack.size(); i++) // // { // // if (ReadPLCPack[i] == array)ifHas = true; // // } // // if (ifHas == false) // // { // // // // }*/ // // read_Mutex->lock(); // // if (!ReadPLCPack.contains(array)) // // ReadPLCPack.append(array); // // read_Mutex->unlock(); // // Sleep(m_sleepTime); // } // catch (QString ev) // { // qDebug() << "[TCP] " << "readCommond failed!" << Num; // } // return true; //} //写单个寄存器指令,封装为报文 bool Hd_SocketModule_ModbusTcp::writeCommond(QString DM, QString type, QVectorvec_value) { try { if (DM.isEmpty() || vec_value.isEmpty()) { qCritical() << "[TCP] " << " DM or Num is null!"; return false; } PLCPack temp; temp.type = type; temp.num = QString::number(vec_value.size()); temp.value = vec_value; temp.address = DM; //int mm_pos = DM.toInt(); //int mm_value = Num.toInt(); //mm_pos = abs(mm_pos); //// mm_value = abs(mm_value); //DM = UShortToHex(mm_pos); //Num = UShortToHex(mm_value); //QString ret = "46 49 4E 53 00 00 00 1C 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 "+ socketIp +" 00 00 01 02 82 " + DM + "00 00 01 " + Num; //QByteArray array = QByteArray::fromHex(ret.toLatin1()); // 使用 16 进制格式 write_Mutex->lock(); //if(!WritePLCPack.contains(temp)) WritePLCPack.enqueue(temp); write_Mutex->unlock(); } catch (QString ev) { qDebug() << "[TCP] " << "writeCommond failed!"; } return true; } //读寄存器 bool Hd_SocketModule_ModbusTcp::readCommond(QString DM, QString type, QString Num) { try { if (DM.isEmpty() || Num.isEmpty()) { qCritical() << "[TCP] " << " DM or Num is null!"; return false; } PLCPack temp; temp.type = type; temp.num = Num; temp.value = QVector(); temp.address = DM; read_Mutex->lock(); ReadPLCPack.enqueue(temp); read_Mutex->unlock(); //int mm_pos = DM.toInt(); //int mm_value = Num.toInt(); //DM = UShortToHex(mm_pos); //Num = UShortToHex(mm_value); //QString ret = "46 49 4E 53 00 00 00 1A 00 00 00 02 00 00 00 00 80 00 02 00 32 00 00 " + socketIp + " 00 00 01 01 82 " + DM + " 00 " + Num; //QByteArray array = QByteArray::fromHex(ret.toLatin1()); // 使用16 进制格式 ////WritePack.append(array); //*QByteArray resultArray; //bool isConed = tcpServer(array, resultArray); //decodePack(resultArray);*/ //bool ifHas = false; //for (int i = 0; i < ReadPLCPack.size(); i++) //{ // if (ReadPLCPack[i] == array)ifHas = true; //} //if (ifHas == false) //{ // read_Mutex->lock(); // ReadPLCPack.append(array); // read_Mutex->unlock(); //} } catch (QString ev) { qDebug() << "[TCP] " << "readCommond failed!"; } return true; } MyThread::~MyThread() { if (tcpsocket) { tcpsocket->Disconnect(); QThread::msleep(3000); DeletePtr(tcpsocket); } // 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();*/ tcpsocket->Disconnect(); } qDebug() << "[TCP] " << " Hd_SocketModule_ModbusTcp close tcpsocket success!"; } //断线重连函数 bool MyThread::disReconnects() { //断线重连标志 //bool reResult = false; //if (!(tcpsocket->state() == QAbstractSocket::ConnectedState)) //{ // qCritical() << "[TCP] " << QString("tcp disconected"); // for (int i = 0; i < 5; i++) // { // tcpsocket->bind(QHostAddress::Any); // tcpsocket->connectToHost(m_IP, m_Port.toInt()); // if (tcpsocket->waitForConnected(5)) // { // qWarning() << "[TCP] " << " You have connected to the server again"; // // 发送握手指令 // QString ret = "46 49 4E 53 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 " + socketIp; // QByteArray array = QByteArray::fromHex(ret.toLatin1()); //使用16进制格式 // tcpsocket->write(array); // tcpsocket->waitForReadyRead(); // QByteArray readData = tcpsocket->readAll(); // reResult = true; // break; // } // Sleep(200); // } //} //else // reResult = true; //return reResult; return true; } //线程 run 中初始化 socket void MyThread::run() { qDebug() << "[TCP] " << " run start"; if (init_flag == 0) { /*tcpsocket = new QTcpSocket; tcpsocket->bind(QHostAddress::Any); tcpsocket->abort();*/ if (tcpsocket) { qCritical() << "[TCP] " << QString("[%1:%2] server has been linked").arg(m_IP).arg(m_Port); return; } HDTcpType type = HDTcpType::ModbusTCP; tcpsocket = CreatePtr(type); std::string ip = m_IP.toStdString(); int portxx = m_Port.toInt(); HDTcpStatus rtn = tcpsocket->Connect(ip.c_str(), portxx, (unsigned char)m_Station.toInt()); if (rtn == HDTcpStatus::Success) { qWarning() << "[TCP] " << " You have connected to the server "; init_success = true; } else { qWarning() << "[TCP] " << " Server not connected"; init_success = false; return; } init_flag = 1; qDebug() << "[TCP] " << " run end ----------"; } else if (init_flag == 1) { //开启wile循环来读写 while (true) { if (init_flag == 2) { break; } writeSocketData(); Sleep(2); } } 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; reciveData.append(readData); decodePack();*/ } void MyThread::decodePack() { QString str; //解析包头 QByteArray head_byte = reciveData.mid(0, 2); // 46 49 转十进制 17993 QByteArray head1_byte = reciveData.mid(2, 2); // 4E 53 转十进制 20051 //转十进制判断包头 if (head_byte.toHex() == "4649" && head1_byte.toHex() == "4e53") { QByteArray len_byte = reciveData.mid(6, 2); //长度 commond 长度 转十进制 QString msg = len_byte.toHex(); int number_len = msg.toInt(NULL, 16); if (number_len == 16) //十六进制的10 十进制为16 备注为握手回复信息 长度为24字节 { reciveData.remove(0, 24); } else if (number_len == m_readPackValue) // 示例: 接受50个数据包的长度 为 122 ,加包头一起为 130 { QByteArray byte = reciveData.mid(0, m_readPackValue + 8); r_Mutex->lock(); readResult = byte; r_Mutex->unlock(); reciveData.remove(0, m_readPackValue + 8); } else { reciveData.remove(0, number_len + 8); // 其他包暂时丢弃,待定处理 } } } //往PLC发报文 void MyThread::writeSocketData() { if (WritePLCPack.isEmpty() && ReadPLCPack.isEmpty()) return; //写PLC if (!WritePLCPack.isEmpty()) { for (int i = 0; i < WritePLCPack.size(); i++) { write_Mutex->lock(); if (!(WritePLCPack.size() > 0)) { write_Mutex->unlock(); break; } PLCPack temp = WritePLCPack.dequeue(); // 取出包 write_Mutex->unlock(); if (!disReconnects()) { qDebug() << "[TCP] " << QString("The server cannot be connected. Check the network port"); init_flag = 2; return; } QString type = temp.type; HDTcpStatus rtn = HDTcpStatus::Error; if (temp.address.contains("DM")) temp.address = temp.address.mid(2, temp.address.size() - 2); else if (temp.address.contains("M") || temp.address.contains("D")) temp.address = temp.address.mid(1, temp.address.size() - 1); std::string address = temp.address.toStdString(); if (type == "bool") { int size = temp.num.toInt(); if (v_bool != NULL) { delete[] v_bool; v_bool = NULL; } v_bool = new bool[size]; bool isValid; for (int i = 0; i < size; i++) { if (temp.value[i] == "0" || temp.value[i] == "false")v_bool[i] = false; if (temp.value[i] == "1" || temp.value[i] == "true")v_bool[i] = true; } rtn = tcpsocket->write_Bool(address.c_str(), (unsigned short)size, v_bool); } else if (type == "byte") { int size = temp.num.toInt(); if (v_byte != NULL) { delete[] v_byte; v_byte = NULL; } v_byte = new unsigned char[size]; bool isValid; for (int i = 0; i < size; i++) { QByteArray bb; bb = temp.value[i].toLatin1(); v_byte[i] = bb.data()[0]; } rtn = tcpsocket->write_Byte(address.c_str(), (unsigned short)size, v_byte); } else if (type == "short") { int size = temp.num.toInt(); if (v_short != NULL) { delete[] v_short; v_short = NULL; } v_short = new short[size]; bool isValid; for (int i = 0; i < size; i++) { v_short[i] = temp.value[i].toShort(&isValid); if (!isValid)v_short[i] = 0; } rtn = tcpsocket->write_Short(address.c_str(), (unsigned short)size, v_short); //std::cout << "write short" << std::endl; } else if (type == "ushort") { int size = temp.num.toInt(); if (v_ushort != NULL) { delete[] v_ushort; v_ushort = NULL; } v_ushort = new unsigned short[size]; bool isValid; for (int i = 0; i < size; i++) { v_ushort[i] = temp.value[i].toUShort(&isValid); if (!isValid)v_ushort[i] = 0; } rtn = tcpsocket->write_Ushort(address.c_str(), (unsigned short)size, v_ushort); } else if (type == "int") { int size = temp.num.toInt(); if (v_int != NULL) { delete[] v_int; v_int = NULL; } v_int = new int[size]; bool isValid; for (int i = 0; i < size; i++) { v_int[i] = temp.value[i].toInt(&isValid); if (!isValid)v_int[i] = 0; } rtn = tcpsocket->write_Int(address.c_str(), (unsigned short)size, v_int); //std::cout << "write short" << std::endl; } else if (type == "uint") { int size = temp.num.toInt(); if (v_uint != NULL) { delete[] v_uint; v_uint = NULL; } v_uint = new unsigned int[size]; bool isValid; for (int i = 0; i < size; i++) { v_uint[i] = temp.value[i].toUInt(&isValid); if (!isValid)v_uint[i] = 0; } rtn = tcpsocket->write_UInt(address.c_str(), (unsigned short)size, v_uint); //std::cout << "write short" << std::endl; } else if (type == "long") { int size = temp.num.toInt(); if (v_longlong != NULL) { delete[] v_longlong; v_longlong = NULL; } v_longlong = new long long[size]; bool isValid; for (int i = 0; i < size; i++) { v_longlong[i] = temp.value[i].toLongLong(&isValid); if (!isValid)v_longlong[i] = 0; } rtn = tcpsocket->write_Long(address.c_str(), (unsigned short)size, v_longlong); //std::cout << "write short" << std::endl; } else if (type == "ulong") { int size = temp.num.toInt(); if (v_ulonglong != NULL) { delete[] v_ulonglong; v_ulonglong = NULL; } v_ulonglong = new unsigned long long[size]; bool isValid; for (int i = 0; i < size; i++) { v_ulonglong[i] = temp.value[i].toULongLong(&isValid); if (!isValid)v_ulonglong[i] = 0; } rtn = tcpsocket->write_ULong(address.c_str(), (unsigned short)size, v_ulonglong); //std::cout << "write short" << std::endl; } else if (type == "float") { int size = temp.num.toInt(); if (v_float != NULL) { delete[] v_float; v_float = NULL; } v_float = new float[size]; bool isValid; for (int i = 0; i < size; i++) { v_float[i] = temp.value[i].toFloat(&isValid); if (!isValid)v_float[i] = 0; } rtn = tcpsocket->write_Float(address.c_str(), (unsigned short)size, v_float); } else if (type == "double") { int size = temp.num.toInt(); if (v_double != NULL) { delete[] v_double; v_double = NULL; } v_double = new double[size]; bool isValid; for (int i = 0; i < size; i++) { v_double[i] = temp.value[i].toDouble(&isValid); if (!isValid)v_double[i] = 0; } rtn = tcpsocket->write_Double(address.c_str(), (unsigned short)size, v_double); } else if (type == "string") { std::string str = ""; for (int i = 0; i < temp.value.size(); i++) { std::string v = temp.value[i].toStdString(); if (i == temp.value.size() - 1) { str = str + v; } else { str = str + v + ","; } } rtn = tcpsocket->write_String(address.c_str(), str.c_str()); } if (rtn == HDTcpStatus::Error) { read_Mutex->lock(); connectStatus = false; read_Mutex->unlock(); std::cout << "通讯断开连接" << std::endl; } else { read_Mutex->lock(); connectStatus = true; read_Mutex->unlock(); } } } // 读PLC read_Mutex->lock(); if (ReadPLCPack.isEmpty()) { read_Mutex->unlock(); return; } PLCPack pack = ReadPLCPack.dequeue(); // 取出包 read_Mutex->unlock(); if (!disReconnects()) { qDebug() << "[TCP] " << QString("The server cannot be connected. Check the network port"); init_flag = 2; return; } /*tcpsocket->write(byte); tcpsocket->waitForBytesWritten(3000); tcpsocket->flush();*/ if(pack.address.contains("M") || pack.address.contains("D")) pack.address = pack.address.mid(1, pack.address.size() - 1); std::string address = pack.address.toStdString(); QByteArray readData; HDTcpStatus rtn1 = HDTcpStatus::Error; if (pack.type == "bool") { int size = pack.num.toInt(); if (v_bool != nullptr) { delete[] v_bool; v_bool = nullptr; } v_bool = new bool[size]; rtn1 = tcpsocket->read_Bool(address.c_str(), (unsigned short)size, v_bool); for (int i = 0; i < size; i++) { char v = v_bool[i] ? 1 : 0; readData.append(v); } } else if (pack.type == "byte") { int size = pack.num.toInt(); if (v_byte != nullptr) { delete[] v_byte; v_byte = nullptr; } v_byte = new unsigned char[size * 2]; rtn1 = tcpsocket->read_Byte(address.c_str(), (unsigned short)size, v_byte); for (int i = 0; i < size * 2; i++) { char v = (char)v_byte[i]; readData.append(v); } //std::cout << "read bytes" << std::endl; } else if (pack.type == "short") { int size = pack.num.toInt(); if (v_short != nullptr) { delete[] v_short; v_short = nullptr; } v_short = new short[size]; rtn1 = tcpsocket->read_Short(address.c_str(), (unsigned short)size, v_short); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_short[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "ushort") { int size = pack.num.toInt(); if (v_ushort != nullptr) { delete[] v_ushort; v_ushort = nullptr; } v_ushort = new unsigned short[size]; rtn1 = tcpsocket->read_Ushort(address.c_str(), (unsigned short)size, v_ushort); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_ushort[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "int") { int size = pack.num.toInt(); if (v_int != nullptr) { delete[] v_int; v_int = nullptr; } v_int = new int[size]; rtn1 = tcpsocket->read_Int(address.c_str(), (unsigned short)size, v_int); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_int[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "uint") { int size = pack.num.toInt(); if (v_uint != nullptr) { delete[] v_uint; v_uint = nullptr; } v_uint = new unsigned int[size]; rtn1 = tcpsocket->read_Uint(address.c_str(), (unsigned short)size, v_uint); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_uint[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "long") { int size = pack.num.toInt(); if (v_longlong != nullptr) { delete[] v_longlong; v_longlong = nullptr; } v_longlong = new long long[size]; rtn1 = tcpsocket->read_Long(address.c_str(), (unsigned short)size, v_longlong); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_longlong[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "ulong") { int size = pack.num.toInt(); if (v_ulonglong != nullptr) { delete[] v_ulonglong; v_ulonglong = nullptr; } v_ulonglong = new unsigned long long[size]; rtn1 = tcpsocket->read_Ulong(address.c_str(), (unsigned short)size, v_ulonglong); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_ulonglong[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "float") { int size = pack.num.toInt(); if (v_float != nullptr) { delete[] v_float; v_float = nullptr; } v_float = new float[size]; rtn1 = tcpsocket->read_Float(address.c_str(), (unsigned short)size, v_float); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_float[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "double") { int size = pack.num.toInt(); if (v_double != nullptr) { delete[] v_double; v_double = nullptr; } v_double = new double[size]; rtn1 = tcpsocket->read_Double(address.c_str(), (unsigned short)size, v_double); for (int i = 0; i < size; i++) { QByteArray bb = QString::number(v_double[i]).toUtf8(); readData.append(bb); } } else if (pack.type == "string") { int size = pack.num.toInt(); if (v_char != nullptr) { delete[] v_char; v_char = nullptr; } v_char = new char[size]; rtn1 = tcpsocket->read_String(address.c_str(), (unsigned short)size, v_char); for (int i = 0; i < size; i++) { readData.append(v_char[i]); } } if (rtn1 == HDTcpStatus::Error) { read_Mutex->lock(); connectStatus = false; read_Mutex->unlock(); std::cout << "通讯断开连接" << std::endl; } else { read_Mutex->lock(); connectStatus = true; read_Mutex->unlock(); } r_Mutex->lock(); readResult = readData; /*if (readData != "") readResult = "";*/ r_Mutex->unlock(); //reciveData.append(readData); //int timeOut = 0; //while (1) //{ // timeOut++; // if (timeOut > 500)break; // Sleep(1);//必须要刷新进程 // qApp->processEvents(); // if (!disReconnects()) // { // qDebug() << "[TCP] " << QString("The server cannot be connected. Check the network port"); // init_flag = 2; // return; // } // // /*tcpsocket->waitForReadyRead(); // QByteArray readData = tcpsocket->readAll();*/ // if (readData.isEmpty()) // continue; // reciveData.append(readData); // decodePack(); // break; //} //return; } void MyThread::setReadPackValue(int value) { m_readPackValue = 22 + value * 2; } //检查异常标志 bool Hd_SocketModule_ModbusTcp::checkStatus() { read_Mutex->lock(); bool connectStatus1 = connectStatus; read_Mutex->unlock(); return connectStatus1; }