#include "sendprogthread.h" #include "gutil/qnetwork.h" #include #include #include #include #include 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 fileNames = QDir(prog_dir).entryList(QDir::Files); if(fileNames.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())+") "+tcp.errorString()+" at waitForConnected"); tcp.close(); return; } if(stoped) { tcp.close(); return; }; //发送节目列表协商 JArray files; for(auto &name : fileNames) if(name!="program") { QFileInfo info(prog_dir+"/"+name); files.append(JObj{{"name", info.baseName()}, {"size", info.size()}}); } if(! files.empty()) { JObj req; req.insert("_type", "consult"); req.insert("files", files); req.insert("idList", JArray{"aaa"}); req.insert("zVer", "xixun1"); auto resNum = tcp.write(JToBytes(req)); tcp.flush(); if(resNum == -1 || ! tcp.waitForBytesWritten() || ! tcp.waitForReadyRead()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at waitForRead 'checkExist'"); tcp.close(); return; } auto resp = tcp.readAll(); QString error; auto res = JFrom(resp, &error); while(error.contains("end-of-input")) { if(! tcp.waitForReadyRead()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at waitForRead2 'checkExist'"); tcp.close(); return; } resp += tcp.readAll(); error = ""; res = JFrom(resp, &error); } if(! error.isEmpty()) { emit emErr(error+" at parse 'checkExist'"); tcp.close(); return; } auto existeds = res["existed"].toArray(); for(auto &existed : existeds) fileNames.removeAll(existed.toString()); } if(stoped) { tcp.close(); return; } qint64 progSize = 0; for(auto &name : fileNames) progSize += QFileInfo(prog_dir+"/"+name).size(); if(progSize == 0) { emit emErr(tr("Program is empty")); tcp.close(); return; } auto req = JObj(); req.insert("_type", "proStart"); req.insert("proName", "program"); req.insert("proSize", progSize); req.insert("zVer","xixun1"); auto resNum = tcp.write(JToBytes(req)); tcp.flush(); if(resNum == -1 || ! tcp.waitForBytesWritten()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write 'proStart'"); tcp.close(); return; } if(stoped) { tcp.close(); return; } //4.发送协商列表应答里的文件 int64_t sentBytes = 0; char buf[8192]; for(auto &name : fileNames) { QFileInfo info(prog_dir+"/"+name); auto baseName = info.baseName(); auto remain = info.size(); req = JObj(); req.insert("_type", "fileStart"); req.insert("id", baseName); req.insert("size", remain); req.insert("zVer","xixun1"); auto resNum = tcp.write(JToBytes(req)); if(resNum == -1) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write 'fileStart'"); tcp.close(); return; } auto file = new QFile(info.filePath()); if(! file->open(QFile::ReadOnly)) { emit emErr(tr("Open file failed")+" "+file->errorString()); tcp.close(); return; } while(remain > 0) { resNum = file->read(buf, qMin(8192LL, remain)); if(resNum <= 0) { emit emErr(tr("Read file failed")+" "+file->errorString()); tcp.close(); file->close(); return; } if(stoped) { tcp.close(); file->close(); return; }; if(! tcp.waitForBytesWritten(60000)) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at waitForWritten file: "+file->fileName()); tcp.close(); file->close(); return; } resNum = tcp.write(buf, resNum); if(resNum <= 0) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write file: "+file->fileName()); 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 = JObj(); req.insert("_type", "fileEnd"); req.insert("id", baseName); req.insert("zVer", "xixun1"); resNum = tcp.write(JToBytes(req)); tcp.flush(); if(resNum == -1 || ! tcp.waitForBytesWritten()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write 'fileEnd'"); tcp.close(); return; } } if(stoped) { tcp.close(); return; }; //5.发送结束 req = JObj(); req.insert("_type", "proEnd"); req.insert("proName", "program"); req.insert("zVer","xixun1"); resNum = tcp.write(JToBytes(req)); tcp.flush(); if(resNum == -1 || ! tcp.waitForBytesWritten()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write 'proEnd'"); tcp.close(); return; }; if(! tcp.waitForReadyRead()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at waitForRead 'proEnd'"); tcp.close(); return; } auto resp = tcp.readAll(); if(resp.isEmpty()) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at read 'proEnd'"); tcp.close(); return; } tcp.close(); emit emProgress(100); emit emErr("OK"); }