2025-06-16 23:41:35 +08:00
|
|
|
#include "FileTrans.h"
|
2025-06-18 14:53:56 +08:00
|
|
|
|
2025-06-18 13:18:31 +08:00
|
|
|
#include <QFileInfo>
|
2025-06-16 23:41:35 +08:00
|
|
|
|
|
|
|
|
FileTrans::FileTrans(ClientCore* clientCore) : clientCore_(clientCore)
|
|
|
|
|
{
|
2025-06-19 15:37:39 +08:00
|
|
|
RegisterSignal();
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_ = QSharedPointer<DoTransTask>::create();
|
|
|
|
|
sendTask_ = QSharedPointer<DoTransTask>::create();
|
2025-06-16 23:41:35 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-18 13:18:31 +08:00
|
|
|
/*
|
|
|
|
|
* When the local client actively sends a file, it cannot simultaneously perform download operations.
|
|
|
|
|
* Passive sending is an exception, primarily to monitor the sending progress. In contrast,
|
|
|
|
|
* the progress of passive sending is monitored by the requesting download side,
|
|
|
|
|
* so there is no need to track the progress locally.
|
|
|
|
|
*/
|
|
|
|
|
void FileTrans::ReqSendFile(const TransTask& task)
|
2025-06-16 23:41:35 +08:00
|
|
|
{
|
2025-06-18 13:18:31 +08:00
|
|
|
// TODO: check if running...
|
2025-06-20 13:03:27 +08:00
|
|
|
if (sendTask_->file.isOpen()) {
|
|
|
|
|
qWarning() << QString(tr("file [%1] is running.")).arg(sendTask_->file.fileName());
|
|
|
|
|
while (sendTask_->file.isOpen()) {
|
|
|
|
|
QThread::msleep(1);
|
|
|
|
|
}
|
|
|
|
|
qWarning() << QString(tr("file [%1] is exit running.")).arg(sendTask_->file.fileName());
|
|
|
|
|
}
|
2025-06-18 13:18:31 +08:00
|
|
|
// start
|
|
|
|
|
InfoMsg info;
|
|
|
|
|
info.toPath = task.remotePath;
|
|
|
|
|
info.fromPath = task.localPath;
|
|
|
|
|
|
2025-06-18 14:53:56 +08:00
|
|
|
sendTask_->file.setFileName(info.fromPath);
|
|
|
|
|
if (!sendTask_->file.open(QIODevice::ReadOnly)) {
|
|
|
|
|
qCritical() << QString(tr("open file [%1] failed.")).arg(info.fromPath);
|
|
|
|
|
sendTask_->state = TaskState::STATE_NONE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 13:18:31 +08:00
|
|
|
QFileInfo fileInfo(info.fromPath);
|
|
|
|
|
if (fileInfo.exists()) {
|
|
|
|
|
qint64 size = fileInfo.size();
|
|
|
|
|
info.permissions = static_cast<quint32>(fileInfo.permissions());
|
|
|
|
|
info.size = size;
|
|
|
|
|
} else {
|
2025-06-18 14:53:56 +08:00
|
|
|
qCritical() << QString(tr("File [%1] not exit.")).arg(info.fromPath);
|
|
|
|
|
sendTask_->file.close();
|
2025-06-18 13:18:31 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
|
2025-06-19 15:37:39 +08:00
|
|
|
auto frame = clientCore_->GetBuffer(info, FBT_CLI_REQ_SEND, task.remoteId);
|
2025-06-20 14:33:51 +08:00
|
|
|
if (!ClientCore::syncInvoke(clientCore_, [this, frame]() { return clientCore_->Send(frame); })) {
|
2025-06-18 14:53:56 +08:00
|
|
|
qCritical() << QString(tr("send req send failed: %1")).arg(info.msg);
|
|
|
|
|
sendTask_->state = TaskState::STATE_NONE;
|
|
|
|
|
sendTask_->file.close();
|
2025-06-18 13:18:31 +08:00
|
|
|
return;
|
2025-06-18 14:53:56 +08:00
|
|
|
}
|
|
|
|
|
sendTask_->state = TaskState::STATE_RUNNING;
|
|
|
|
|
sendTask_->totalSize = info.size;
|
|
|
|
|
sendTask_->tranSize = 0;
|
2025-06-19 22:07:12 +08:00
|
|
|
sendTask_->task = task;
|
2025-06-18 13:18:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FileTrans::ReqDownFile(const TransTask& task)
|
|
|
|
|
{
|
|
|
|
|
// TODO: check if running...
|
|
|
|
|
|
|
|
|
|
// start
|
|
|
|
|
InfoMsg info;
|
|
|
|
|
info.toPath = task.localPath;
|
|
|
|
|
info.fromPath = task.remotePath;
|
|
|
|
|
|
2025-06-20 09:45:39 +08:00
|
|
|
downTask_->task = task;
|
|
|
|
|
downTask_->totalSize = 0;
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->file.setFileName(Util::Get2FilePath(task.remotePath, task.localPath));
|
2025-06-19 11:59:32 +08:00
|
|
|
if (!downTask_->file.open(QIODevice::WriteOnly)) {
|
2025-06-18 14:53:56 +08:00
|
|
|
qCritical() << QString(tr("open file [%1] failed.")).arg(downTask_->file.fileName());
|
2025-06-19 11:59:32 +08:00
|
|
|
downTask_->state = TaskState::STATE_NONE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-06-19 15:37:39 +08:00
|
|
|
auto frame = clientCore_->GetBuffer(info, FBT_CLI_REQ_DOWN, task.remoteId);
|
2025-06-20 14:33:51 +08:00
|
|
|
if (!ClientCore::syncInvoke(clientCore_, [this, frame]() { return clientCore_->Send(frame); })) {
|
2025-06-18 14:53:56 +08:00
|
|
|
qCritical() << QString(tr("send req send failed: %1")).arg(info.msg);
|
2025-06-20 09:45:39 +08:00
|
|
|
downTask_->state = TaskState::STATE_NONE;
|
|
|
|
|
downTask_->file.close();
|
2025-06-18 13:18:31 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-06-20 09:45:39 +08:00
|
|
|
downTask_->state = TaskState::STATE_RUNNING;
|
2025-06-18 13:18:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qint32 FileTrans::GetSendProgress()
|
|
|
|
|
{
|
2025-06-20 09:45:39 +08:00
|
|
|
if (sendTask_->state == TaskState::STATE_FINISH) {
|
2025-06-20 13:03:27 +08:00
|
|
|
sendTask_->state = TaskState::STATE_NONE;
|
2025-06-20 09:45:39 +08:00
|
|
|
return 100;
|
|
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
if (sendTask_->state != TaskState::STATE_RUNNING) {
|
2025-06-18 13:18:31 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2025-06-20 13:03:27 +08:00
|
|
|
|
|
|
|
|
// wait file state ok.
|
2025-06-18 14:53:56 +08:00
|
|
|
double per = (sendTask_->tranSize * 100.0) / sendTask_->totalSize;
|
2025-06-20 13:03:27 +08:00
|
|
|
qint32 rt = static_cast<qint32>(per);
|
|
|
|
|
if (rt >= 100) {
|
|
|
|
|
return 99;
|
|
|
|
|
}
|
|
|
|
|
return rt;
|
2025-06-18 13:18:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qint32 FileTrans::GetDownProgress()
|
|
|
|
|
{
|
2025-06-20 09:45:39 +08:00
|
|
|
if (downTask_->state == TaskState::STATE_FINISH) {
|
2025-06-20 13:03:27 +08:00
|
|
|
downTask_->state = TaskState::STATE_NONE;
|
2025-06-20 09:45:39 +08:00
|
|
|
return 100;
|
|
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
if (downTask_->state != TaskState::STATE_RUNNING) {
|
2025-06-18 13:18:31 +08:00
|
|
|
return -1;
|
|
|
|
|
}
|
2025-06-20 09:45:39 +08:00
|
|
|
if (downTask_->totalSize == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2025-06-20 13:03:27 +08:00
|
|
|
// wait file state ok.
|
2025-06-18 14:53:56 +08:00
|
|
|
double per = (downTask_->tranSize * 100.0) / downTask_->totalSize;
|
2025-06-20 13:03:27 +08:00
|
|
|
qint32 rt = static_cast<qint32>(per);
|
|
|
|
|
if (rt >= 100) {
|
|
|
|
|
return 99;
|
|
|
|
|
}
|
|
|
|
|
return rt;
|
2025-06-16 23:41:35 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-19 15:37:39 +08:00
|
|
|
void FileTrans::RegisterSignal()
|
2025-06-16 23:41:35 +08:00
|
|
|
{
|
2025-06-19 15:37:39 +08:00
|
|
|
connect(clientCore_, &ClientCore::sigReqSend, this, [this](QSharedPointer<FrameBuffer> frame) { fbtReqSend(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigReqDown, this, [this](QSharedPointer<FrameBuffer> frame) { fbtReqDown(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigTransDone, this, [this](QSharedPointer<FrameBuffer> frame) { fbtTransDone(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigCanSend, this, [this](QSharedPointer<FrameBuffer> frame) { fbtCanSend(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigCanotSend, this, [this](QSharedPointer<FrameBuffer> frame) { fbtCanotSend(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigCanotDown, this, [this](QSharedPointer<FrameBuffer> frame) { fbtCanotDown(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigCanDown, this, [this](QSharedPointer<FrameBuffer> frame) { fbtCanDown(frame); });
|
|
|
|
|
connect(clientCore_, &ClientCore::sigFileBuffer, this, [this](QSharedPointer<FrameBuffer> frame) { fbtFileBuffer(frame); });
|
2025-06-20 09:45:39 +08:00
|
|
|
connect(clientCore_, &ClientCore::sigFileInfo, this, [this](QSharedPointer<FrameBuffer> frame) { fbtFileInfo(frame); });
|
2025-06-19 15:37:39 +08:00
|
|
|
connect(clientCore_, &ClientCore::sigTransFailed, this, [this](QSharedPointer<FrameBuffer> frame) { fbtTransFailed(frame); });
|
2025-06-16 23:41:35 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
// The other party requests to send, prepare to receive.
|
2025-06-16 23:41:35 +08:00
|
|
|
void FileTrans::fbtReqSend(QSharedPointer<FrameBuffer> frame)
|
|
|
|
|
{
|
2025-06-17 16:42:39 +08:00
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
2025-06-19 11:59:32 +08:00
|
|
|
qInfo() << QString(tr("%1 req send: %2 to %3")).arg(frame->fid).arg(info.fromPath, info.toPath);
|
2025-06-17 11:48:13 +08:00
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
// judge is same client's same file.
|
2025-06-17 12:00:46 +08:00
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
// recv is single thread recv, judge idle
|
2025-06-18 14:53:56 +08:00
|
|
|
if (downTask_->state == TaskState::STATE_RUNNING) {
|
2025-06-17 16:50:36 +08:00
|
|
|
info.msg = QString(tr("busy..."));
|
2025-06-19 15:37:39 +08:00
|
|
|
auto f = clientCore_->GetBuffer(info, FBT_CLI_CANOT_SEND, frame->fid);
|
2025-06-20 14:33:51 +08:00
|
|
|
ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); });
|
2025-06-17 11:48:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// recv
|
2025-06-17 16:42:39 +08:00
|
|
|
auto newerPath = Util::Get2FilePath(info.fromPath, info.toPath);
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->file.setFileName(newerPath);
|
|
|
|
|
if (!downTask_->file.open(QIODevice::WriteOnly)) {
|
2025-06-17 16:42:39 +08:00
|
|
|
info.msg = QString(tr("open file failed: %1")).arg(newerPath);
|
2025-06-17 11:48:13 +08:00
|
|
|
qCritical() << info.msg;
|
2025-06-19 15:37:39 +08:00
|
|
|
auto f = clientCore_->GetBuffer(info, FBT_CLI_CANOT_SEND, frame->fid);
|
2025-06-20 14:33:51 +08:00
|
|
|
if (!ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); })) {
|
2025-06-19 15:37:39 +08:00
|
|
|
qCritical() << QString(tr("open recv file:%2 failed, and reply %2 failed.")).arg(info.msg, f->fid);
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->file.close();
|
2025-06-17 11:48:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-06-17 16:42:39 +08:00
|
|
|
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->totalSize = info.size;
|
|
|
|
|
downTask_->tranSize = 0;
|
|
|
|
|
downTask_->permission = info.permissions;
|
2025-06-17 16:42:39 +08:00
|
|
|
|
|
|
|
|
info.msg = QString(tr("open recv file success: %1")).arg(newerPath);
|
2025-06-19 22:31:34 +08:00
|
|
|
qInfo() << info.msg;
|
2025-06-19 11:59:32 +08:00
|
|
|
auto f = clientCore_->GetBuffer(info, FBT_CLI_CAN_SEND, frame->fid);
|
2025-06-20 14:33:51 +08:00
|
|
|
if (!ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); })) {
|
2025-06-19 11:59:32 +08:00
|
|
|
qCritical() << QString(tr("open recv file:%2 success, but reply %2 failed.")).arg(info.msg, frame->fid);
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->file.close();
|
2025-06-17 11:48:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->state = TaskState::STATE_RUNNING;
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
// 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;
|
|
|
|
|
}
|
2025-06-20 09:45:39 +08:00
|
|
|
|
|
|
|
|
QFileInfo fileInfo(info.fromPath);
|
|
|
|
|
if (fileInfo.exists()) {
|
|
|
|
|
qint64 size = fileInfo.size();
|
|
|
|
|
info.permissions = static_cast<quint32>(fileInfo.permissions());
|
|
|
|
|
info.size = size;
|
|
|
|
|
} else {
|
|
|
|
|
qCritical() << QString(tr("File [%1] not exit.")).arg(info.fromPath);
|
|
|
|
|
doTask->file.close();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reply fileinfo
|
|
|
|
|
auto f = clientCore_->GetBuffer(info, FBT_CLI_FILE_INFO, frame->fid);
|
2025-06-20 14:33:51 +08:00
|
|
|
if (!ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); })) {
|
2025-06-20 09:45:39 +08:00
|
|
|
qCritical() << QString(tr("send file %1 info failed.")).arg(info.fromPath);
|
|
|
|
|
doTask->file.close();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-06-17 16:42:39 +08:00
|
|
|
doTask->task.isUpload = true;
|
|
|
|
|
doTask->task.localPath = info.fromPath;
|
|
|
|
|
doTask->task.remoteId = frame->fid;
|
|
|
|
|
SendFile(doTask);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-17 11:48:13 +08:00
|
|
|
void FileTrans::fbtTransDone(QSharedPointer<FrameBuffer> frame)
|
|
|
|
|
{
|
|
|
|
|
auto info = infoUnpack<InfoMsg>(frame->data);
|
2025-06-18 14:53:56 +08:00
|
|
|
if (downTask_->file.isOpen()) {
|
|
|
|
|
downTask_->file.close();
|
|
|
|
|
downTask_->state = TaskState::STATE_FINISH;
|
2025-06-19 22:31:34 +08:00
|
|
|
info.msg = QString(tr("recv file:%1 success.")).arg(downTask_->file.fileName());
|
|
|
|
|
qInfo() << info.msg;
|
2025-06-19 15:37:39 +08:00
|
|
|
auto f = clientCore_->GetBuffer(info, FBT_CLI_CAN_DOWN, frame->fid);
|
2025-06-20 14:33:51 +08:00
|
|
|
ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); });
|
2025-06-17 11:48:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
qCritical() << QString(tr("recv file:%1 done sigal, but file not opened.")).arg(info.msg);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:50:36 +08:00
|
|
|
// the other party indicates that can download, ready to receive the file.
|
2025-06-17 16:42:39 +08:00
|
|
|
void FileTrans::fbtCanDown(QSharedPointer<FrameBuffer> frame)
|
2025-06-17 11:48:13 +08:00
|
|
|
{
|
2025-06-17 16:50:36 +08:00
|
|
|
// ready to recv file.
|
|
|
|
|
auto info = infoUnpack<InfoMsg>(frame->data);
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->permission = info.permissions;
|
|
|
|
|
downTask_->totalSize = info.size;
|
|
|
|
|
downTask_->tranSize = 0;
|
2025-06-17 16:50:36 +08:00
|
|
|
qDebug() << QString(tr("start trans file:%1.")).arg(info.fromPath);
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
void FileTrans::fbtCanotDown(QSharedPointer<FrameBuffer> frame)
|
2025-06-17 11:48:13 +08:00
|
|
|
{
|
|
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
2025-06-19 11:59:32 +08:00
|
|
|
qCritical() << QString(tr("request send file:%1 failed. reason:%2")).arg(info.fromPath, info.msg);
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
void FileTrans::fbtFileBuffer(QSharedPointer<FrameBuffer> frame)
|
2025-06-17 11:48:13 +08:00
|
|
|
{
|
2025-06-18 14:53:56 +08:00
|
|
|
if (downTask_->state != TaskState::STATE_RUNNING) {
|
2025-06-17 11:48:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// For the sake of efficiency, not verify the legality of the file
|
2025-06-18 14:53:56 +08:00
|
|
|
auto ws = downTask_->file.write(frame->data.constData(), frame->data.size());
|
2025-06-17 11:48:13 +08:00
|
|
|
if (ws != frame->data.size()) {
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->state = TaskState::STATE_FAILED;
|
2025-06-17 11:48:13 +08:00
|
|
|
InfoMsg info;
|
2025-06-18 14:53:56 +08:00
|
|
|
info.msg = downTask_->file.errorString();
|
2025-06-19 15:37:39 +08:00
|
|
|
auto f = clientCore_->GetBuffer(info, FBT_CLI_TRANS_FAILED, frame->fid);
|
2025-06-20 14:33:51 +08:00
|
|
|
ClientCore::syncInvoke(clientCore_, [this, f]() { return clientCore_->Send(f); });
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->file.close();
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->tranSize += ws;
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-20 09:45:39 +08:00
|
|
|
void FileTrans::fbtFileInfo(QSharedPointer<FrameBuffer> frame)
|
|
|
|
|
{
|
|
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
|
|
|
|
qInfo() << QString(tr("prepare downfile's size is:%1, perm:%2")).arg(info.size, info.permissions);
|
|
|
|
|
downTask_->totalSize = info.size;
|
|
|
|
|
downTask_->tranSize = 0;
|
|
|
|
|
downTask_->permission = info.permissions;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
void FileTrans::fbtCanotSend(QSharedPointer<FrameBuffer> frame)
|
2025-06-17 11:48:13 +08:00
|
|
|
{
|
2025-06-17 12:00:46 +08:00
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
2025-06-19 11:59:32 +08:00
|
|
|
qCritical() << QString(tr("request file:%1 failed. reason:%2")).arg(info.fromPath, info.msg);
|
2025-06-18 14:53:56 +08:00
|
|
|
if (sendTask_->file.isOpen()) {
|
|
|
|
|
sendTask_->file.close();
|
|
|
|
|
}
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
void FileTrans::fbtCanSend(QSharedPointer<FrameBuffer> frame)
|
2025-06-17 11:48:13 +08:00
|
|
|
{
|
2025-06-18 14:53:56 +08:00
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
2025-06-19 11:59:32 +08:00
|
|
|
qInfo() << QString(tr("start trans file:%1 to %2")).arg(info.fromPath, frame->fid);
|
2025-06-18 14:53:56 +08:00
|
|
|
SendFile(sendTask_);
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 16:42:39 +08:00
|
|
|
void FileTrans::fbtTransFailed(QSharedPointer<FrameBuffer> frame)
|
2025-06-17 11:48:13 +08:00
|
|
|
{
|
2025-06-18 14:53:56 +08:00
|
|
|
qCritical() << QString(tr("trans file:%1 failed.")).arg(downTask_->file.fileName());
|
|
|
|
|
if (downTask_->file.isOpen()) {
|
|
|
|
|
downTask_->file.close();
|
2025-06-17 16:42:39 +08:00
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
downTask_->state = TaskState::STATE_FAILED;
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FileTrans::SendFile(const QSharedPointer<DoTransTask>& task)
|
|
|
|
|
{
|
|
|
|
|
auto* sendThread = new SendThread(clientCore_);
|
|
|
|
|
sendThread->setTask(task);
|
|
|
|
|
QMutexLocker locker(&sthMut_);
|
2025-06-18 13:18:31 +08:00
|
|
|
// TODO: check if already exist
|
|
|
|
|
upTasks_[task->task.localId] = sendThread;
|
2025-06-17 11:48:13 +08:00
|
|
|
sendThread->run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SendThread::SendThread(ClientCore* clientCore) : cliCore_(clientCore)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendThread::run()
|
|
|
|
|
{
|
|
|
|
|
// task's file shoule be already opened.
|
2025-06-19 11:59:32 +08:00
|
|
|
isSuccess_ = true;
|
2025-06-17 11:48:13 +08:00
|
|
|
while (!task_->file.atEnd()) {
|
2025-06-19 22:07:12 +08:00
|
|
|
|
|
|
|
|
auto frame = QSharedPointer<FrameBuffer>::create();
|
|
|
|
|
frame->tid = task_->task.remoteId;
|
|
|
|
|
frame->type = FBT_CLI_FILE_BUFFER;
|
|
|
|
|
frame->call = [this](QSharedPointer<FrameBuffer> frame) { sendCall(frame); };
|
2025-06-17 11:48:13 +08:00
|
|
|
frame->data.resize(CHUNK_BUF_SIZE);
|
2025-06-19 22:07:12 +08:00
|
|
|
|
2025-06-17 11:48:13 +08:00
|
|
|
auto br = task_->file.read(frame->data.data(), CHUNK_BUF_SIZE);
|
|
|
|
|
if (br == -1) {
|
|
|
|
|
qCritical() << QString(tr("read file failed: %1")).arg(task_->file.errorString());
|
2025-06-19 11:59:32 +08:00
|
|
|
isSuccess_ = false;
|
2025-06-17 11:48:13 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
frame->data.resize(br);
|
2025-06-19 11:59:32 +08:00
|
|
|
|
|
|
|
|
while (curSendCount_ >= MAX_SEND_TASK) {
|
|
|
|
|
QThread::msleep(1);
|
|
|
|
|
// shoule add abort action mark.
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-19 16:20:01 +08:00
|
|
|
QMetaObject::invokeMethod(cliCore_, [this, frame] {
|
2025-06-19 11:59:32 +08:00
|
|
|
frame->sendRet = cliCore_->Send(frame);
|
|
|
|
|
if (frame->call) {
|
|
|
|
|
frame->call(frame);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
++curSendCount_;
|
|
|
|
|
|
|
|
|
|
if (!isSuccess_) {
|
2025-06-17 11:48:13 +08:00
|
|
|
qCritical() << QString(tr("send to %1 file failed.")).arg(task_->task.remoteId);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-19 22:07:12 +08:00
|
|
|
|
|
|
|
|
while (curSendCount_ > 0) {
|
|
|
|
|
QThread::msleep(1);
|
|
|
|
|
// shoule add abort action mark.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InfoMsg info;
|
|
|
|
|
auto f = cliCore_->GetBuffer(info, FBT_CLI_TRANS_DONE, task_->task.remoteId);
|
2025-06-20 14:33:51 +08:00
|
|
|
ClientCore::syncInvoke(cliCore_, [this, f]() { return cliCore_->Send(f); });
|
2025-06-18 14:53:56 +08:00
|
|
|
task_->file.close();
|
2025-06-20 13:03:27 +08:00
|
|
|
task_->state = TaskState::STATE_FINISH;
|
2025-06-17 11:48:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendThread::setTask(const QSharedPointer<DoTransTask>& task)
|
|
|
|
|
{
|
|
|
|
|
task_ = task;
|
2025-06-19 11:59:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendThread::sendCall(QSharedPointer<FrameBuffer> frame)
|
|
|
|
|
{
|
|
|
|
|
if (frame->sendRet) {
|
|
|
|
|
--curSendCount_;
|
|
|
|
|
task_->tranSize += frame->data.size();
|
|
|
|
|
} else {
|
|
|
|
|
isSuccess_ = false;
|
|
|
|
|
}
|
|
|
|
|
}
|