2025-06-16 23:41:35 +08:00
|
|
|
#include "ClientCore.h"
|
2025-06-14 23:25:16 +08:00
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
ClientCore::ClientCore(QObject* parent) : QObject(parent)
|
|
|
|
|
{
|
2025-06-15 20:37:25 +08:00
|
|
|
socket_ = new QTcpSocket(this);
|
|
|
|
|
connect(socket_, &QTcpSocket::readyRead, this, &ClientCore::onReadyRead);
|
|
|
|
|
connect(socket_, &QTcpSocket::disconnected, this, &ClientCore::onDisconnected);
|
2025-06-14 23:25:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClientCore::~ClientCore()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClientCore::Connect(const QString& ip, quint16 port)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&conMutex_);
|
|
|
|
|
if (!locker.isLocked()) {
|
|
|
|
|
qWarning() << QString(tr("%1:%2 already connecting...")).arg(ip).arg(port);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
socket_->connectToHost(ip, port);
|
|
|
|
|
if (!socket_->waitForConnected(3000)) {
|
|
|
|
|
qCritical() << QString(tr("%1:%2 connect failed...")).arg(ip).arg(port);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-06-15 20:37:25 +08:00
|
|
|
qInfo() << QString(tr("%1:%2 connected success.")).arg(ip).arg(port);
|
2025-06-14 23:25:16 +08:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientCore::Disconnect()
|
|
|
|
|
{
|
|
|
|
|
}
|
2025-06-14 23:44:13 +08:00
|
|
|
|
|
|
|
|
void ClientCore::onReadyRead()
|
|
|
|
|
{
|
|
|
|
|
QByteArray data = socket_->readAll();
|
|
|
|
|
recvBuffer_.append(data);
|
|
|
|
|
while (true) {
|
|
|
|
|
auto frame = Protocol::ParseBuffer(recvBuffer_);
|
|
|
|
|
if (frame == nullptr) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
UseFrame(frame);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientCore::onDisconnected()
|
|
|
|
|
{
|
|
|
|
|
qCritical() << QString("client %1 disconnected...").arg(remoteID_);
|
2025-06-19 11:59:32 +08:00
|
|
|
emit sigDisconnect();
|
2025-06-14 23:44:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientCore::UseFrame(QSharedPointer<FrameBuffer> frame)
|
|
|
|
|
{
|
2025-06-15 20:37:25 +08:00
|
|
|
switch (frame->type) {
|
|
|
|
|
case FrameBufferType::FBT_SER_MSG_ASKCLIENTS: {
|
|
|
|
|
InfoClientVec info = infoUnpack<InfoClientVec>(frame->data);
|
|
|
|
|
clientsCall_(info);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FrameBufferType::FBT_SER_MSG_YOURID: {
|
|
|
|
|
ownID_ = frame->data;
|
|
|
|
|
qInfo() << QString(tr("own id: %1")).arg(ownID_);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-06-15 23:13:30 +08:00
|
|
|
case FrameBufferType::FBT_CLI_ANS_DIRFILE: {
|
|
|
|
|
DirFileInfoVec info = infoUnpack<DirFileInfoVec>(frame->data);
|
|
|
|
|
fileCall_(info);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FrameBufferType::FBT_CLI_ASK_DIRFILE: {
|
|
|
|
|
DirFileInfoVec vec;
|
|
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
|
|
|
|
if (!localFile_.GetDirFile(info.msg, vec)) {
|
|
|
|
|
qWarning() << QString(tr("get dir file failed use %1")).arg(info.msg);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!Send<DirFileInfoVec>(vec, FBT_CLI_ANS_DIRFILE, frame->fid)) {
|
|
|
|
|
qCritical() << QString(tr("send dir file result failed."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FrameBufferType::FBT_CLI_ASK_HOME: {
|
|
|
|
|
InfoMsg info;
|
|
|
|
|
info.msg = Util::GetUserHome();
|
|
|
|
|
auto data = infoPack<InfoMsg>(info);
|
|
|
|
|
if (!Send<InfoMsg>(info, FBT_CLI_ANS_HOME, frame->fid)) {
|
|
|
|
|
qCritical() << QString(tr("send home failed."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case FrameBufferType::FBT_CLI_ANS_HOME: {
|
|
|
|
|
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
|
|
|
|
qInfo() << QString(tr("home: %1")).arg(info.msg);
|
|
|
|
|
pathCall_(info.msg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-06-18 15:10:28 +08:00
|
|
|
case FrameBufferType::FBT_SER_MSG_FORWARD_FAILED: {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-06-15 20:37:25 +08:00
|
|
|
default:
|
2025-06-16 23:41:35 +08:00
|
|
|
frameCall_[static_cast<uint32_t>(frame->type)](frame);
|
2025-06-15 20:37:25 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2025-06-14 23:44:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClientCore::Send(QSharedPointer<FrameBuffer> frame)
|
|
|
|
|
{
|
|
|
|
|
if (frame == nullptr) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
auto data = Protocol::PackBuffer(frame);
|
|
|
|
|
if (data.size() == 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return Send(data.constData(), data.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClientCore::Send(const char* data, qint64 len)
|
|
|
|
|
{
|
|
|
|
|
if (socket_->state() != QAbstractSocket::ConnectedState) {
|
|
|
|
|
qCritical() << QString("client %1 not connected...").arg(remoteID_);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-06-17 11:48:13 +08:00
|
|
|
|
|
|
|
|
qint64 bytesWritten = -1;
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&sockMut_);
|
|
|
|
|
bytesWritten = socket_->write(data, len);
|
|
|
|
|
}
|
2025-06-14 23:44:13 +08:00
|
|
|
if (bytesWritten == -1 || !socket_->waitForBytesWritten(5000)) {
|
|
|
|
|
qCritical() << QString("Send data to server failed. %1").arg(socket_->errorString());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-06-15 14:31:54 +08:00
|
|
|
|
|
|
|
|
void ClientCore::SetClientsCall(const std::function<void(const InfoClientVec& clients)>& call)
|
|
|
|
|
{
|
2025-06-15 20:37:25 +08:00
|
|
|
clientsCall_ = call;
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientCore::SetPathCall(const std::function<void(const QString& path)>& call)
|
|
|
|
|
{
|
2025-06-15 20:37:25 +08:00
|
|
|
pathCall_ = call;
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientCore::SetFileCall(const std::function<void(const DirFileInfoVec& files)>& call)
|
|
|
|
|
{
|
2025-06-15 20:37:25 +08:00
|
|
|
fileCall_ = call;
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClientCore::SetRemoteID(const QString& id)
|
|
|
|
|
{
|
2025-06-15 23:13:30 +08:00
|
|
|
remoteID_ = id;
|
2025-06-15 14:31:54 +08:00
|
|
|
}
|
|
|
|
|
|
2025-06-16 23:41:35 +08:00
|
|
|
void ClientCore::SetFrameCall(FrameBufferType type, const std::function<void(QSharedPointer<FrameBuffer>)>& call)
|
2025-06-16 20:06:49 +08:00
|
|
|
{
|
|
|
|
|
frameCall_[type] = call;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
QString ClientCore::GetRemoteID()
|
|
|
|
|
{
|
|
|
|
|
return remoteID_;
|
|
|
|
|
}
|
2025-06-18 14:53:56 +08:00
|
|
|
|
|
|
|
|
QString ClientCore::GetOwnID()
|
|
|
|
|
{
|
|
|
|
|
return ownID_;
|
|
|
|
|
}
|
2025-06-19 11:59:32 +08:00
|
|
|
|
|
|
|
|
SocketWorker::SocketWorker(ClientCore* core, QObject* parent) : QThread(parent), core_(core)
|
|
|
|
|
{
|
|
|
|
|
connect(core_, &ClientCore::sigDisconnect, this, [this]() {
|
|
|
|
|
emit disconnected();
|
|
|
|
|
thread()->quit();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SocketWorker::~SocketWorker()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SocketWorker::SetConnectInfo(const QString& ip, qint16 port)
|
|
|
|
|
{
|
|
|
|
|
ip_ = ip;
|
|
|
|
|
port_ = port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SocketWorker::run()
|
|
|
|
|
{
|
|
|
|
|
emit connecting();
|
|
|
|
|
if (!core_->Connect(ip_, port_)) {
|
|
|
|
|
emit conFailed();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
emit conSuccess();
|
|
|
|
|
exec();
|
|
|
|
|
}
|