diff --git a/ClientCore/FileTrans.cpp b/ClientCore/FileTrans.cpp index 8efd667..d893d73 100644 --- a/ClientCore/FileTrans.cpp +++ b/ClientCore/FileTrans.cpp @@ -13,59 +13,51 @@ void FileTrans::SetTasks(const QVector& tasks) void FileTrans::RegisterFrameCall() { clientCore_->SetFrameCall(FBT_CLI_REQ_SEND, [this](QSharedPointer frame) { fbtReqSend(frame); }); - clientCore_->SetFrameCall(FBT_CLI_REQ_RECV, [this](QSharedPointer frame) { fbtReqRecv(frame); }); + clientCore_->SetFrameCall(FBT_CLI_REQ_DOWN, [this](QSharedPointer frame) { fbtReqDown(frame); }); clientCore_->SetFrameCall(FBT_CLI_TRANS_DONE, [this](QSharedPointer frame) { fbtTransDone(frame); }); - clientCore_->SetFrameCall(FBT_CLI_ANSSEND_SUCCESS, [this](QSharedPointer frame) { fbtAnsSendSuccess(frame); }); - clientCore_->SetFrameCall(FBT_CLI_ANSSEND_FAILED, [this](QSharedPointer frame) { fbtAnsSendFailed(frame); }); - clientCore_->SetFrameCall(FBT_CLI_ANSRECV_FAILED, [this](QSharedPointer frame) { fbtAnsRecvFailed(frame); }); - clientCore_->SetFrameCall(FBT_CLI_ANSRECV_SUCCESS, [this](QSharedPointer frame) { fbtAnsRecvSuccess(frame); }); - clientCore_->SetFrameCall(FBT_CLI_FILETRANS, [this](QSharedPointer frame) { fbtFileTrans(frame); }); - clientCore_->SetFrameCall(FBT_CLI_FILETRANS_FAILED, [this](QSharedPointer frame) { fbtFileTransFailed(frame); }); + clientCore_->SetFrameCall(FBT_CLI_CAN_SEND, [this](QSharedPointer frame) { fbtCanSend(frame); }); + clientCore_->SetFrameCall(FBT_CLI_CANOT_SEND, [this](QSharedPointer frame) { fbtCanotSend(frame); }); + clientCore_->SetFrameCall(FBT_CLI_CANOT_DOWN, [this](QSharedPointer frame) { fbtCanotDown(frame); }); + clientCore_->SetFrameCall(FBT_CLI_CAN_DOWN, [this](QSharedPointer frame) { fbtCanDown(frame); }); + clientCore_->SetFrameCall(FBT_CLI_FILE_BUFFER, [this](QSharedPointer frame) { fbtFileBuffer(frame); }); + clientCore_->SetFrameCall(FBT_CLI_TRANS_FAILED, [this](QSharedPointer frame) { fbtTransFailed(frame); }); } +// The other party requests to send, prepare to receive. void FileTrans::fbtReqSend(QSharedPointer frame) { - // judget is same client's same file. - - // judget if file exits etc. - - // send InfoMsg info = infoUnpack(frame->data); - auto doTask = QSharedPointer::create(); - doTask->file.setFileName(info.path); - if (!doTask->file.open(QIODevice::ReadOnly)) { - qCritical() << QString(tr("open file failed: %1")).arg(info.path); + qInfo() << QString(tr("%1 req send: %2 to %3")).arg(frame->fid).arg(info.fromPath).arg(info.toPath); + + // judge is same client's same file. + + // recv is single thread recv, judge idle + if (downTask_.state == TaskState::STATE_RUNNING) { + info.msg = QString(tr("busy")); + clientCore_->Send(info, FBT_CLI_CANOT_SEND, frame->fid); return; } - doTask->task.isUpload = true; - doTask->task.localPath = info.path; - doTask->task.remoteId = frame->fid; - SendFile(doTask); -} - -void FileTrans::fbtReqRecv(QSharedPointer frame) -{ - // recv is single thread recv. - - // judge idle - - // reply msg // recv - InfoMsg info = infoUnpack(frame->data); - downTask_.file.setFileName(info.path); + auto newerPath = Util::Get2FilePath(info.fromPath, info.toPath); + downTask_.file.setFileName(newerPath); if (!downTask_.file.open(QIODevice::WriteOnly)) { - info.msg = QString(tr("open file failed: %1")).arg(info.path); + info.msg = QString(tr("open file failed: %1")).arg(newerPath); qCritical() << info.msg; - if (!clientCore_->Send(info, FBT_CLI_ANSRECV_FAILED, frame->fid)) { + if (!clientCore_->Send(info, FBT_CLI_CANOT_SEND, frame->fid)) { qCritical() << QString(tr("open recv file:%2 failed, and reply %2 failed.")).arg(info.msg).arg(frame->fid); downTask_.file.close(); return; } return; } - info.msg = QString(tr("open recv file success: %1")).arg(info.path); - if (!clientCore_->Send(info, FBT_CLI_ANSRECV_SUCCESS, frame->fid)) { + + downTask_.totalSize = info.size; + downTask_.tranSize = 0; + downTask_.permission = info.permissions; + + info.msg = QString(tr("open recv file success: %1")).arg(newerPath); + if (!clientCore_->Send(info, FBT_CLI_CAN_SEND, frame->fid)) { qCritical() << QString(tr("open recv file:%2 success, but reply %2 failed.")).arg(info.msg).arg(frame->fid); downTask_.file.close(); return; @@ -73,6 +65,27 @@ void FileTrans::fbtReqRecv(QSharedPointer frame) downTask_.state = TaskState::STATE_RUNNING; } +// The other party requests to download, prepare to send. +void FileTrans::fbtReqDown(QSharedPointer frame) +{ + InfoMsg info = infoUnpack(frame->data); + // judge is same client's same file. + + // judge if file exits etc. + + // send + auto doTask = QSharedPointer::create(); + doTask->file.setFileName(info.fromPath); + if (!doTask->file.open(QIODevice::ReadOnly)) { + qCritical() << QString(tr("open file failed: %1")).arg(info.fromPath); + return; + } + doTask->task.isUpload = true; + doTask->task.localPath = info.fromPath; + doTask->task.remoteId = frame->fid; + SendFile(doTask); +} + void FileTrans::fbtTransDone(QSharedPointer frame) { auto info = infoUnpack(frame->data); @@ -80,35 +93,35 @@ void FileTrans::fbtTransDone(QSharedPointer frame) downTask_.file.close(); downTask_.state = TaskState::STATE_FINISH; qInfo() << QString(tr("recv file:%1 success.")).arg(downTask_.file.fileName()); - clientCore_->Send(info, FBT_CLI_ANSRECV_SUCCESS, frame->fid); + clientCore_->Send(info, FBT_CLI_CAN_DOWN, frame->fid); return; } qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg); } -void FileTrans::fbtAnsRecvSuccess(QSharedPointer frame) +void FileTrans::fbtCanDown(QSharedPointer frame) { // ready to send InfoMsg info = infoUnpack(frame->data); auto doTask = QSharedPointer::create(); - doTask->file.setFileName(info.path); + doTask->file.setFileName(info.fromPath); if (!doTask->file.open(QIODevice::ReadOnly)) { - qCritical() << QString(tr("open file failed: %1")).arg(info.path); + qCritical() << QString(tr("open file failed: %1")).arg(info.fromPath); return; } doTask->task.isUpload = true; - doTask->task.localPath = info.path; + doTask->task.localPath = ""; doTask->task.remoteId = frame->fid; SendFile(doTask); } -void FileTrans::fbtAnsRecvFailed(QSharedPointer frame) +void FileTrans::fbtCanotDown(QSharedPointer frame) { InfoMsg info = infoUnpack(frame->data); - qCritical() << QString(tr("request send file:%1 failed. reason:%2")).arg(info.path).arg(info.msg); + qCritical() << QString(tr("request send file:%1 failed. reason:%2")).arg(info.fromPath).arg(info.msg); } -void FileTrans::fbtFileTrans(QSharedPointer frame) +void FileTrans::fbtFileBuffer(QSharedPointer frame) { if (downTask_.state != TaskState::STATE_RUNNING) { return; @@ -119,22 +132,27 @@ void FileTrans::fbtFileTrans(QSharedPointer frame) downTask_.state = TaskState::STATE_FAILED; InfoMsg info; info.msg = downTask_.file.errorString(); - clientCore_->Send(info, FBT_CLI_FILETRANS_FAILED, frame->fid); + clientCore_->Send(info, FBT_CLI_TRANS_FAILED, frame->fid); } } -void FileTrans::fbtAnsSendFailed(QSharedPointer frame) +void FileTrans::fbtCanotSend(QSharedPointer frame) { InfoMsg info = infoUnpack(frame->data); - qCritical() << QString(tr("request file:%1 failed. reason:%2")).arg(info.path).arg(info.msg); + qCritical() << QString(tr("request file:%1 failed. reason:%2")).arg(info.fromPath).arg(info.msg); } -void FileTrans::fbtAnsSendSuccess(QSharedPointer frame) +void FileTrans::fbtCanSend(QSharedPointer frame) { } -void FileTrans::fbtFileTransFailed(QSharedPointer frame) +void FileTrans::fbtTransFailed(QSharedPointer frame) { + qCritical() << QString(tr("trans file:%1 failed.")).arg(downTask_.file.fileName()); + if (downTask_.file.isOpen()) { + downTask_.file.close(); + } + downTask_.state = TaskState::STATE_FAILED; } void FileTrans::SendFile(const QSharedPointer& task) @@ -155,7 +173,7 @@ void SendThread::run() // task's file shoule be already opened. auto frame = QSharedPointer::create(); frame->tid = task_->task.remoteId; - frame->type = FBT_CLI_FILETRANS; + frame->type = FBT_CLI_FILE_BUFFER; bool suc = true; while (!task_->file.atEnd()) { diff --git a/ClientCore/FileTrans.h b/ClientCore/FileTrans.h index 1b15620..3ef2fd5 100644 --- a/ClientCore/FileTrans.h +++ b/ClientCore/FileTrans.h @@ -27,6 +27,9 @@ enum class TaskState { struct DoTransTask { QFile file; + quint64 totalSize{0}; + quint64 tranSize{0}; + quint32 permission{}; TaskState state = TaskState::STATE_NONE; TransTask task; }; @@ -58,14 +61,14 @@ public: private: void fbtReqSend(QSharedPointer frame); - void fbtReqRecv(QSharedPointer frame); + void fbtReqDown(QSharedPointer frame); void fbtTransDone(QSharedPointer frame); - void fbtAnsRecvSuccess(QSharedPointer frame); - void fbtAnsRecvFailed(QSharedPointer frame); - void fbtFileTrans(QSharedPointer frame); - void fbtAnsSendFailed(QSharedPointer frame); - void fbtAnsSendSuccess(QSharedPointer frame); - void fbtFileTransFailed(QSharedPointer frame); + void fbtCanDown(QSharedPointer frame); + void fbtCanotDown(QSharedPointer frame); + void fbtFileBuffer(QSharedPointer frame); + void fbtCanotSend(QSharedPointer frame); + void fbtCanSend(QSharedPointer frame); + void fbtTransFailed(QSharedPointer frame); private: void SendFile(const QSharedPointer& task); diff --git a/Protocol/Protocol.h b/Protocol/Protocol.h index abcf276..1136301 100644 --- a/Protocol/Protocol.h +++ b/Protocol/Protocol.h @@ -11,7 +11,8 @@ constexpr quint32 CHUNK_BUF_SIZE = 1 * 1024 * 1024; // used for communication with the server. // Contents beyond 30 are only forwarded. enum FrameBufferType : uint16_t { - FBT_SER_MSG_ASKCLIENTS = 0, + FBT_NONE = 0, + FBT_SER_MSG_ASKCLIENTS, FBT_SER_MSG_YOURID, FBT_SER_MSG_RESPONSE, FBT_SER_MSG_FORWARD_FAILED, @@ -22,21 +23,21 @@ enum FrameBufferType : uint16_t { FBT_CLI_ASK_HOME, FBT_CLI_ANS_HOME, FBT_CLI_REQ_SEND, - FBT_CLI_ANSSEND_SUCCESS, - FBT_CLI_ANSSEND_FAILED, - FBT_CLI_REQ_RECV, - FBT_CLI_ANSRECV_SUCCESS, - FBT_CLI_ANSRECV_FAILED, - FBT_CLI_FILETRANS, + FBT_CLI_CAN_SEND, + FBT_CLI_CANOT_SEND, + FBT_CLI_REQ_DOWN, + FBT_CLI_CAN_DOWN, + FBT_CLI_CANOT_DOWN, + FBT_CLI_FILE_BUFFER, FBT_CLI_TRANS_DONE, - FBT_CLI_FILETRANS_FAILED + FBT_CLI_TRANS_FAILED }; struct FrameBuffer { QByteArray data; QString fid; QString tid; - FrameBufferType type; + FrameBufferType type = FBT_NONE; }; class Protocol diff --git a/Struct/InfoMsg.h b/Struct/InfoMsg.h index 0a8cbbc..90f094f 100644 --- a/Struct/InfoMsg.h +++ b/Struct/InfoMsg.h @@ -10,20 +10,23 @@ struct InfoMsg { qint32 mark{}; QString msg; - QString path; + QString fromPath; + QString toPath; + quint64 size{}; + quint32 permissions{}; void serialize(QDataStream& data) const { - data << mark << msg << path; + data << mark << msg << fromPath << toPath << size << permissions; } void deserialize(QDataStream& data) { - data >> mark >> msg >> path; + data >> mark >> msg >> fromPath >> toPath >> size >> permissions; } }; QDataStream& operator<<(QDataStream& data, const InfoMsg& info); QDataStream& operator>>(QDataStream& data, InfoMsg& info); -#endif // INFO_MSG_H \ No newline at end of file +#endif // INFO_MSG_H \ No newline at end of file diff --git a/Util/Util.cpp b/Util/Util.cpp index 4cab047..7a32871 100644 --- a/Util/Util.cpp +++ b/Util/Util.cpp @@ -1,4 +1,4 @@ -#include "Util.h" +#include "Util.h" #include #include @@ -45,6 +45,34 @@ void Util::InitLogger(const QString& logPath, const QString& mark) spdlog::register_logger(logger); } +#include +#include + +QString Util::Get2FilePath(const QString& file, const QString& directory) +{ + if (file.isEmpty() || directory.isEmpty()) { + return QString(); + } + + QFileInfo fileInfo(file); + QDir dir(directory); + + if (!fileInfo.isFile()) { + qWarning() << "Path A is not a file:" << file; + return QString(); + } + if (!dir.exists()) { + qWarning() << "Path B is not a valid directory:" << directory; + return QString(); + } + + QString fileName = fileInfo.fileName(); + QString cleanPathB = QDir::cleanPath(directory); + QString newPath = cleanPathB + QDir::separator() + fileName; + newPath = QDir::cleanPath(newPath); + return newPath; +} + void Util::ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg) { Q_UNUSED(context); diff --git a/Util/Util.h b/Util/Util.h index a4ea895..2992898 100644 --- a/Util/Util.h +++ b/Util/Util.h @@ -1,4 +1,4 @@ -#ifndef UTIL_H +#ifndef UTIL_H #define UTIL_H #include @@ -13,6 +13,7 @@ public: public: static QString GetUserHome(); static void InitLogger(const QString& logPath, const QString& mark); + static QString Get2FilePath(const QString& file, const QString& directory); static void ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg); };