qt/LedOK/wProgramManager/sendprogthread.cpp

225 lines
8.0 KiB
C++
Raw Normal View History

2022-08-25 18:37:24 +08:00
#include "sendprogthread.h"
#include <QHostAddress>
#include <QDir>
#include <QJsonArray>
#include <QDirIterator>
#include <QMessageBox>
#include <QMetaEnum>
SendProgThread::SendProgThread(const QString &progDir, const QString &ip, int port) : prog_dir(progDir), ip(ip), port(port) {
connect(this, &QThread::finished, this, &QThread::deleteLater);
}
void SendProgThread::run() {
emit emProgress(0); // 进度条归零
auto fileInfos = QDir(prog_dir).entryInfoList(QDir::Files);
if(fileInfos.isEmpty()) {
emit emErr(tr("Program is empty"));
return;
}
if(stoped) return;
TcpSocket tcp;
tcp.connectToHost(ip, port);
if(! tcp.waitForConnected()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when waitForConnected");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
if(stoped) {
tcp.close();
return;
};
//发送节目列表协商
QJsonArray ids;
foreach(auto fileInfo, fileInfos) {
auto baseName = fileInfo.baseName();
if(baseName!="program") ids.append(baseName);
}
if(! ids.isEmpty()) {
QJsonObject req;
req.insert("_type", "consult");
req.insert("proName", "program");
req.insert("idList", ids);
req.insert("zVer", "xixun1");
auto requ = QJsonDocument(req).toJson(QJsonDocument::Compact);
auto resNum = tcp.write(requ);
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when write 'consult'. size"+QString::number(requ.size()));
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
if(! tcp.waitForReadyRead()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when waitForRead 'consult'. size"+QString::number(requ.size()));
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
auto resp = tcp.readAll();
if(resp.isEmpty()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when read 'consult'. size"+QString::number(requ.size()));
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
if(stoped) {
tcp.close();
return;
};
QJsonParseError parseErr;
QJsonDocument res = QJsonDocument::fromJson(resp, &parseErr);
for(int i=2; parseErr.error == QJsonParseError::UnterminatedString && i < 10; i++) {
if(! tcp.waitForReadyRead()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when waitForRead 'consult' "+QString::number(i));
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
auto resp2 = tcp.readAll();
if(resp2.isEmpty()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when read 'consult' "+QString::number(i));
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
resp += resp2;
res = QJsonDocument::fromJson(resp, &parseErr);
}
if(parseErr.error != QJsonParseError::NoError) {
emit emErr(parseErr.errorString()+" when parse consult. size:"+QString::number(resp.size()));
tcp.close();
return;
}
if(res["_type"].toString()=="consult") {
fileInfos.clear();
fileInfos.append(QString(prog_dir+"/program"));
2022-08-25 18:37:24 +08:00
QJsonArray ids = res["idList"].toArray();
foreach(auto id, ids) fileInfos.append(QString(prog_dir+"/"+id.toString()));
2022-08-25 18:37:24 +08:00
}
}
if(stoped) {
tcp.close();
return;
2022-10-27 15:07:45 +08:00
}
2022-08-25 18:37:24 +08:00
qint64 progSize = 0;
foreach(auto fileInfo, fileInfos) progSize += fileInfo.size();
if(progSize == 0) {
emit emErr(tr("Program is empty"));
tcp.close();
return;
}
auto req = QJsonObject();
req.insert("_type", "proStart");
req.insert("proName", "program");
req.insert("proSize", progSize);
req.insert("zVer","xixun1");
auto resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when write 'proStart'");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
2022-10-27 15:07:45 +08:00
}
2022-08-25 18:37:24 +08:00
if(stoped) {
tcp.close();
return;
2022-10-27 15:07:45 +08:00
}
2022-08-25 18:37:24 +08:00
//4.发送协商列表应答里的文件
long long sentBytes = 0;
foreach(auto info, fileInfos) if(info.isFile()) {
auto baseName = info.baseName();
auto remain = info.size();
req = QJsonObject();
req.insert("_type", "fileStart");
req.insert("id", baseName);
req.insert("size", remain);
req.insert("relative_path", "");
req.insert("zVer","xixun1");
auto resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when write 'fileStart'");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
auto file = new QFile(info.filePath());
if(! file->open(QFile::ReadOnly)) {
emit emErr(tr("Open file failed")+" "+file->errorString());
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
while(remain > 0) {
auto readed = file->read(qMin(4096LL, remain));
if(readed.isEmpty()) {
emit emErr(tr("Read file failed")+" "+file->errorString());
tcp.close();
file->close();
return;
}
if(stoped) {
tcp.close();
file->close();
return;
};
resNum = tcp.write(readed);
if(resNum == -1) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when write file: "+file->fileName());
2022-08-25 18:37:24 +08:00
tcp.close();
file->close();
return;
}
if(! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when waitForWritten file: "+file->fileName());
2022-08-25 18:37:24 +08:00
tcp.close();
file->close();
return;
}
if(stoped) {
tcp.close();
file->close();
return;
};
remain -= resNum;
sentBytes += resNum;
if(sentBytes != 0) emit emProgress(sentBytes * 99 / progSize);
}
file->close();
if(stoped) {
tcp.close();
return;
};
req = QJsonObject();
req.insert("_type", "fileEnd");
req.insert("id", baseName);
req.insert("zVer", "xixun1");
resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when write 'fileEnd'");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
}
if(stoped) {
tcp.close();
return;
};
//5.发送结束
req = QJsonObject();
req.insert("_type", "proEnd");
req.insert("proName", "program");
req.insert("zVer","xixun1");
resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when write 'proEnd'");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
};
if(! tcp.waitForReadyRead()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when waitForRead 'proEnd'");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
auto resp = tcp.readAll();
if(resp.isEmpty()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") when read 'proEnd'");
2022-08-25 18:37:24 +08:00
tcp.close();
return;
}
tcp.close();
emit emProgress(100);
emit emErr("OK");
}