Files
ds-628/BaseModules/Hd_SocketModule_Snap7Tcp/Hd_SocketModule_Snap7Tcp.cpp
T
2024-09-27 14:31:22 +08:00

1571 lines
38 KiB
C++

#include "Hd_SocketModule_Snap7Tcp.h"
#include "qcoreapplication.h"
bool connectStatus = true;
struct PLCPack
{
QString address;
QString type;
QVector<QString> value;
QString num;
};
static QQueue<PLCPack> WritePLCPack;
//static QQueue<PLCPack> ReadPack;
static QQueue<PLCPack> 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_Snap7Tcp* create()
{
qDebug() << "[INFO] " << "Hd_SocketModule_Snap7Tcp create success!";
return new Hd_SocketModule_Snap7Tcp;
}
void destory(Hd_SocketModule_Snap7Tcp* ptr)
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
qDebug() << "[INFO] " << " Hd_SocketModule_Snap7Tcp destory success!";
}
// 可传递ushort 类型的值 和-1
QString Hd_SocketModule_Snap7Tcp::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_Snap7Tcp::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_Snap7Tcp::Hd_SocketModule_Snap7Tcp()
{
m_Mutex = new QMutex;
m_Thread = new MyThread(this);
m_Thread->setMutexLock(m_Mutex);
}
Hd_SocketModule_Snap7Tcp::~Hd_SocketModule_Snap7Tcp()
{
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_Snap7Tcp success!";
}
bool Hd_SocketModule_Snap7Tcp::readData(std::vector<cv::Mat>& 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] " << "snap7Tcp 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_Snap7Tcp::writeData(std::vector<cv::Mat>& 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;
}
QList<QByteArray> m_list = data.split('_');
QString m_value;
QString m_type;
QString m_ip_lastpos;
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);
m_Rack = m_list.at(3);
m_Slot = m_list.at(4);
m_SiemensType = m_list.at(5);
QStringList list = m_IP.split(".");
if (list.size() == 4)
{
m_ip_lastpos = list.at(3);
}
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
{
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);
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 == "write")
{
QVector<QString> 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<short> 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<QString> 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_Snap7Tcp::decodeWriteResult(QByteArray byte, QVector<QString>& 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_Snap7Tcp::tcpServer(QByteArray cmd, QByteArray& m_resultPack)
{
return false;
}
void Hd_SocketModule_Snap7Tcp::decodePack(QByteArray resultArray)
{
}
//初始化
bool Hd_SocketModule_Snap7Tcp::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);
// 设置收发数据的类型
if (!write_value.isEmpty())
m_writeType = write_value;
qDebug() << "[TCP] " << "list: " << list;
setSleepTimeAndReadNum(sleepvalue.toInt(), readvalue.toInt());
m_Thread->setSocketIp(m_Rack,m_Slot,m_SiemensType);
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();
Sleep(500);
if (!m_Thread->getInitSuccessFlag())
{
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_Snap7Tcp::run()
{
//qDebug() << "[info] " << __FUNCTION__ << " line:" << __LINE__ << " success!";
return true;
}
//通信偷懒时间
void Hd_SocketModule_Snap7Tcp::setSleepTimeAndReadNum(int time, int num)
{
m_sleepTime = time;
m_Thread->setReadPackValue(num);
}
//写单个寄存器指令,封装为报文
//bool Hd_SocketModule_Snap7Tcp::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 = "M" + 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_Snap7Tcp::writeAllCommond(QString DM, QString write_Num, QVector<short> 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 = "M" + 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_Snap7Tcp::writeResultCommond(QString DM, QString write_Num, QVector<QString> 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 = "M" + 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_Snap7Tcp::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 = "M" + 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_Snap7Tcp::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 = "M" + 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_Snap7Tcp::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 = "M" + 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_Snap7Tcp::writeCommond(QString DM, QString type, QVector<QString>vec_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_Snap7Tcp::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<QString>();
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();
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_Snap7Tcp 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::Siemens_Snap7;
tcpsocket = CreatePtr(type);
std::string ip = m_IP.toStdString();
HDTcpStatus rtn = tcpsocket->Connect(ip.c_str(), m_Rack.toInt(), m_Slot.toInt(),m_SiemensType.toInt());
if (rtn == HDTcpStatus::Success)
{
qWarning() << "[TCP] " << " You have connected to the server ";
}
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;
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 || rtn == HDTcpStatus::Fail)
{
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();*/
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 || rtn1 == HDTcpStatus::Fail)
{
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_Snap7Tcp::checkStatus()
{
read_Mutex->lock();
bool connectStatus1 = connectStatus;
read_Mutex->unlock();
return connectStatus1;
}