change: some trans logic.

This commit is contained in:
2025-06-17 16:42:39 +08:00
parent 4b86ebc5c5
commit b0d07e6bc9
6 changed files with 125 additions and 71 deletions

View File

@@ -13,59 +13,51 @@ void FileTrans::SetTasks(const QVector<TransTask>& tasks)
void FileTrans::RegisterFrameCall() void FileTrans::RegisterFrameCall()
{ {
clientCore_->SetFrameCall(FBT_CLI_REQ_SEND, [this](QSharedPointer<FrameBuffer> frame) { fbtReqSend(frame); }); clientCore_->SetFrameCall(FBT_CLI_REQ_SEND, [this](QSharedPointer<FrameBuffer> frame) { fbtReqSend(frame); });
clientCore_->SetFrameCall(FBT_CLI_REQ_RECV, [this](QSharedPointer<FrameBuffer> frame) { fbtReqRecv(frame); }); clientCore_->SetFrameCall(FBT_CLI_REQ_DOWN, [this](QSharedPointer<FrameBuffer> frame) { fbtReqDown(frame); });
clientCore_->SetFrameCall(FBT_CLI_TRANS_DONE, [this](QSharedPointer<FrameBuffer> frame) { fbtTransDone(frame); }); clientCore_->SetFrameCall(FBT_CLI_TRANS_DONE, [this](QSharedPointer<FrameBuffer> frame) { fbtTransDone(frame); });
clientCore_->SetFrameCall(FBT_CLI_ANSSEND_SUCCESS, [this](QSharedPointer<FrameBuffer> frame) { fbtAnsSendSuccess(frame); }); clientCore_->SetFrameCall(FBT_CLI_CAN_SEND, [this](QSharedPointer<FrameBuffer> frame) { fbtCanSend(frame); });
clientCore_->SetFrameCall(FBT_CLI_ANSSEND_FAILED, [this](QSharedPointer<FrameBuffer> frame) { fbtAnsSendFailed(frame); }); clientCore_->SetFrameCall(FBT_CLI_CANOT_SEND, [this](QSharedPointer<FrameBuffer> frame) { fbtCanotSend(frame); });
clientCore_->SetFrameCall(FBT_CLI_ANSRECV_FAILED, [this](QSharedPointer<FrameBuffer> frame) { fbtAnsRecvFailed(frame); }); clientCore_->SetFrameCall(FBT_CLI_CANOT_DOWN, [this](QSharedPointer<FrameBuffer> frame) { fbtCanotDown(frame); });
clientCore_->SetFrameCall(FBT_CLI_ANSRECV_SUCCESS, [this](QSharedPointer<FrameBuffer> frame) { fbtAnsRecvSuccess(frame); }); clientCore_->SetFrameCall(FBT_CLI_CAN_DOWN, [this](QSharedPointer<FrameBuffer> frame) { fbtCanDown(frame); });
clientCore_->SetFrameCall(FBT_CLI_FILETRANS, [this](QSharedPointer<FrameBuffer> frame) { fbtFileTrans(frame); }); clientCore_->SetFrameCall(FBT_CLI_FILE_BUFFER, [this](QSharedPointer<FrameBuffer> frame) { fbtFileBuffer(frame); });
clientCore_->SetFrameCall(FBT_CLI_FILETRANS_FAILED, [this](QSharedPointer<FrameBuffer> frame) { fbtFileTransFailed(frame); }); clientCore_->SetFrameCall(FBT_CLI_TRANS_FAILED, [this](QSharedPointer<FrameBuffer> frame) { fbtTransFailed(frame); });
} }
// The other party requests to send, prepare to receive.
void FileTrans::fbtReqSend(QSharedPointer<FrameBuffer> frame) void FileTrans::fbtReqSend(QSharedPointer<FrameBuffer> frame)
{ {
// judget is same client's same file.
// judget if file exits etc.
// send
InfoMsg info = infoUnpack<InfoMsg>(frame->data); InfoMsg info = infoUnpack<InfoMsg>(frame->data);
auto doTask = QSharedPointer<DoTransTask>::create(); qInfo() << QString(tr("%1 req send: %2 to %3")).arg(frame->fid).arg(info.fromPath).arg(info.toPath);
doTask->file.setFileName(info.path);
if (!doTask->file.open(QIODevice::ReadOnly)) { // judge is same client's same file.
qCritical() << QString(tr("open file failed: %1")).arg(info.path);
// recv is single thread recv, judge idle
if (downTask_.state == TaskState::STATE_RUNNING) {
info.msg = QString(tr("busy"));
clientCore_->Send<InfoMsg>(info, FBT_CLI_CANOT_SEND, frame->fid);
return; return;
} }
doTask->task.isUpload = true;
doTask->task.localPath = info.path;
doTask->task.remoteId = frame->fid;
SendFile(doTask);
}
void FileTrans::fbtReqRecv(QSharedPointer<FrameBuffer> frame)
{
// recv is single thread recv.
// judge idle
// reply msg
// recv // recv
InfoMsg info = infoUnpack<InfoMsg>(frame->data); auto newerPath = Util::Get2FilePath(info.fromPath, info.toPath);
downTask_.file.setFileName(info.path); downTask_.file.setFileName(newerPath);
if (!downTask_.file.open(QIODevice::WriteOnly)) { 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; qCritical() << info.msg;
if (!clientCore_->Send<InfoMsg>(info, FBT_CLI_ANSRECV_FAILED, frame->fid)) { if (!clientCore_->Send<InfoMsg>(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); qCritical() << QString(tr("open recv file:%2 failed, and reply %2 failed.")).arg(info.msg).arg(frame->fid);
downTask_.file.close(); downTask_.file.close();
return; return;
} }
return; return;
} }
info.msg = QString(tr("open recv file success: %1")).arg(info.path);
if (!clientCore_->Send<InfoMsg>(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<InfoMsg>(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); qCritical() << QString(tr("open recv file:%2 success, but reply %2 failed.")).arg(info.msg).arg(frame->fid);
downTask_.file.close(); downTask_.file.close();
return; return;
@@ -73,6 +65,27 @@ void FileTrans::fbtReqRecv(QSharedPointer<FrameBuffer> frame)
downTask_.state = TaskState::STATE_RUNNING; downTask_.state = TaskState::STATE_RUNNING;
} }
// The other party requests to download, prepare to send.
void FileTrans::fbtReqDown(QSharedPointer<FrameBuffer> frame)
{
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
// judge is same client's same file.
// judge if file exits etc.
// send
auto doTask = QSharedPointer<DoTransTask>::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<FrameBuffer> frame) void FileTrans::fbtTransDone(QSharedPointer<FrameBuffer> frame)
{ {
auto info = infoUnpack<InfoMsg>(frame->data); auto info = infoUnpack<InfoMsg>(frame->data);
@@ -80,35 +93,35 @@ void FileTrans::fbtTransDone(QSharedPointer<FrameBuffer> frame)
downTask_.file.close(); downTask_.file.close();
downTask_.state = TaskState::STATE_FINISH; downTask_.state = TaskState::STATE_FINISH;
qInfo() << QString(tr("recv file:%1 success.")).arg(downTask_.file.fileName()); qInfo() << QString(tr("recv file:%1 success.")).arg(downTask_.file.fileName());
clientCore_->Send<InfoMsg>(info, FBT_CLI_ANSRECV_SUCCESS, frame->fid); clientCore_->Send<InfoMsg>(info, FBT_CLI_CAN_DOWN, frame->fid);
return; return;
} }
qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg); qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg);
} }
void FileTrans::fbtAnsRecvSuccess(QSharedPointer<FrameBuffer> frame) void FileTrans::fbtCanDown(QSharedPointer<FrameBuffer> frame)
{ {
// ready to send // ready to send
InfoMsg info = infoUnpack<InfoMsg>(frame->data); InfoMsg info = infoUnpack<InfoMsg>(frame->data);
auto doTask = QSharedPointer<DoTransTask>::create(); auto doTask = QSharedPointer<DoTransTask>::create();
doTask->file.setFileName(info.path); doTask->file.setFileName(info.fromPath);
if (!doTask->file.open(QIODevice::ReadOnly)) { 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; return;
} }
doTask->task.isUpload = true; doTask->task.isUpload = true;
doTask->task.localPath = info.path; doTask->task.localPath = "";
doTask->task.remoteId = frame->fid; doTask->task.remoteId = frame->fid;
SendFile(doTask); SendFile(doTask);
} }
void FileTrans::fbtAnsRecvFailed(QSharedPointer<FrameBuffer> frame) void FileTrans::fbtCanotDown(QSharedPointer<FrameBuffer> frame)
{ {
InfoMsg info = infoUnpack<InfoMsg>(frame->data); InfoMsg info = infoUnpack<InfoMsg>(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<FrameBuffer> frame) void FileTrans::fbtFileBuffer(QSharedPointer<FrameBuffer> frame)
{ {
if (downTask_.state != TaskState::STATE_RUNNING) { if (downTask_.state != TaskState::STATE_RUNNING) {
return; return;
@@ -119,22 +132,27 @@ void FileTrans::fbtFileTrans(QSharedPointer<FrameBuffer> frame)
downTask_.state = TaskState::STATE_FAILED; downTask_.state = TaskState::STATE_FAILED;
InfoMsg info; InfoMsg info;
info.msg = downTask_.file.errorString(); info.msg = downTask_.file.errorString();
clientCore_->Send<InfoMsg>(info, FBT_CLI_FILETRANS_FAILED, frame->fid); clientCore_->Send<InfoMsg>(info, FBT_CLI_TRANS_FAILED, frame->fid);
} }
} }
void FileTrans::fbtAnsSendFailed(QSharedPointer<FrameBuffer> frame) void FileTrans::fbtCanotSend(QSharedPointer<FrameBuffer> frame)
{ {
InfoMsg info = infoUnpack<InfoMsg>(frame->data); InfoMsg info = infoUnpack<InfoMsg>(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<FrameBuffer> frame) void FileTrans::fbtCanSend(QSharedPointer<FrameBuffer> frame)
{ {
} }
void FileTrans::fbtFileTransFailed(QSharedPointer<FrameBuffer> frame) void FileTrans::fbtTransFailed(QSharedPointer<FrameBuffer> 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<DoTransTask>& task) void FileTrans::SendFile(const QSharedPointer<DoTransTask>& task)
@@ -155,7 +173,7 @@ void SendThread::run()
// task's file shoule be already opened. // task's file shoule be already opened.
auto frame = QSharedPointer<FrameBuffer>::create(); auto frame = QSharedPointer<FrameBuffer>::create();
frame->tid = task_->task.remoteId; frame->tid = task_->task.remoteId;
frame->type = FBT_CLI_FILETRANS; frame->type = FBT_CLI_FILE_BUFFER;
bool suc = true; bool suc = true;
while (!task_->file.atEnd()) { while (!task_->file.atEnd()) {

View File

@@ -27,6 +27,9 @@ enum class TaskState {
struct DoTransTask { struct DoTransTask {
QFile file; QFile file;
quint64 totalSize{0};
quint64 tranSize{0};
quint32 permission{};
TaskState state = TaskState::STATE_NONE; TaskState state = TaskState::STATE_NONE;
TransTask task; TransTask task;
}; };
@@ -58,14 +61,14 @@ public:
private: private:
void fbtReqSend(QSharedPointer<FrameBuffer> frame); void fbtReqSend(QSharedPointer<FrameBuffer> frame);
void fbtReqRecv(QSharedPointer<FrameBuffer> frame); void fbtReqDown(QSharedPointer<FrameBuffer> frame);
void fbtTransDone(QSharedPointer<FrameBuffer> frame); void fbtTransDone(QSharedPointer<FrameBuffer> frame);
void fbtAnsRecvSuccess(QSharedPointer<FrameBuffer> frame); void fbtCanDown(QSharedPointer<FrameBuffer> frame);
void fbtAnsRecvFailed(QSharedPointer<FrameBuffer> frame); void fbtCanotDown(QSharedPointer<FrameBuffer> frame);
void fbtFileTrans(QSharedPointer<FrameBuffer> frame); void fbtFileBuffer(QSharedPointer<FrameBuffer> frame);
void fbtAnsSendFailed(QSharedPointer<FrameBuffer> frame); void fbtCanotSend(QSharedPointer<FrameBuffer> frame);
void fbtAnsSendSuccess(QSharedPointer<FrameBuffer> frame); void fbtCanSend(QSharedPointer<FrameBuffer> frame);
void fbtFileTransFailed(QSharedPointer<FrameBuffer> frame); void fbtTransFailed(QSharedPointer<FrameBuffer> frame);
private: private:
void SendFile(const QSharedPointer<DoTransTask>& task); void SendFile(const QSharedPointer<DoTransTask>& task);

View File

@@ -11,7 +11,8 @@ constexpr quint32 CHUNK_BUF_SIZE = 1 * 1024 * 1024;
// used for communication with the server. // used for communication with the server.
// Contents beyond 30 are only forwarded. // Contents beyond 30 are only forwarded.
enum FrameBufferType : uint16_t { enum FrameBufferType : uint16_t {
FBT_SER_MSG_ASKCLIENTS = 0, FBT_NONE = 0,
FBT_SER_MSG_ASKCLIENTS,
FBT_SER_MSG_YOURID, FBT_SER_MSG_YOURID,
FBT_SER_MSG_RESPONSE, FBT_SER_MSG_RESPONSE,
FBT_SER_MSG_FORWARD_FAILED, FBT_SER_MSG_FORWARD_FAILED,
@@ -22,21 +23,21 @@ enum FrameBufferType : uint16_t {
FBT_CLI_ASK_HOME, FBT_CLI_ASK_HOME,
FBT_CLI_ANS_HOME, FBT_CLI_ANS_HOME,
FBT_CLI_REQ_SEND, FBT_CLI_REQ_SEND,
FBT_CLI_ANSSEND_SUCCESS, FBT_CLI_CAN_SEND,
FBT_CLI_ANSSEND_FAILED, FBT_CLI_CANOT_SEND,
FBT_CLI_REQ_RECV, FBT_CLI_REQ_DOWN,
FBT_CLI_ANSRECV_SUCCESS, FBT_CLI_CAN_DOWN,
FBT_CLI_ANSRECV_FAILED, FBT_CLI_CANOT_DOWN,
FBT_CLI_FILETRANS, FBT_CLI_FILE_BUFFER,
FBT_CLI_TRANS_DONE, FBT_CLI_TRANS_DONE,
FBT_CLI_FILETRANS_FAILED FBT_CLI_TRANS_FAILED
}; };
struct FrameBuffer { struct FrameBuffer {
QByteArray data; QByteArray data;
QString fid; QString fid;
QString tid; QString tid;
FrameBufferType type; FrameBufferType type = FBT_NONE;
}; };
class Protocol class Protocol

View File

@@ -10,20 +10,23 @@
struct InfoMsg { struct InfoMsg {
qint32 mark{}; qint32 mark{};
QString msg; QString msg;
QString path; QString fromPath;
QString toPath;
quint64 size{};
quint32 permissions{};
void serialize(QDataStream& data) const void serialize(QDataStream& data) const
{ {
data << mark << msg << path; data << mark << msg << fromPath << toPath << size << permissions;
} }
void deserialize(QDataStream& data) 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, const InfoMsg& info);
QDataStream& operator>>(QDataStream& data, InfoMsg& info); QDataStream& operator>>(QDataStream& data, InfoMsg& info);
#endif // INFO_MSG_H #endif // INFO_MSG_H

View File

@@ -1,4 +1,4 @@
#include "Util.h" #include "Util.h"
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
@@ -45,6 +45,34 @@ void Util::InitLogger(const QString& logPath, const QString& mark)
spdlog::register_logger(logger); spdlog::register_logger(logger);
} }
#include <QDir>
#include <QFileInfo>
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) void Util::ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{ {
Q_UNUSED(context); Q_UNUSED(context);

View File

@@ -1,4 +1,4 @@
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
#include <QObject> #include <QObject>
@@ -13,6 +13,7 @@ public:
public: public:
static QString GetUserHome(); static QString GetUserHome();
static void InitLogger(const QString& logPath, const QString& mark); 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); static void ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg);
}; };