mirror of
https://gitea.msk.dinamika-avia.ru/Constanta-Design/RRJServer.git
synced 2026-03-27 19:45:43 +03:00
537 lines
15 KiB
C++
537 lines
15 KiB
C++
#include "sendsystem.h"
|
|
|
|
SendSystem::SendSystem(QObject *parent) :
|
|
QObject(parent),
|
|
client(nullptr),
|
|
socket(nullptr),
|
|
dataParser(nullptr),
|
|
globalMutex(nullptr),
|
|
buffer(nullptr),
|
|
type(TypeClientAutorization::TYPE_GUI),
|
|
flSendingStopped(false),
|
|
flWaitWritenToSocket(false),
|
|
bytesWritedToSocket(0),
|
|
fileSize(0),
|
|
countSend(0)
|
|
{
|
|
qDebug() << "SendSystem init thread ID " << QThread::currentThreadId();
|
|
|
|
buffer = new char[sendFileBlockSize];
|
|
}
|
|
|
|
SendSystem::~SendSystem()
|
|
{
|
|
delete buffer;
|
|
}
|
|
|
|
|
|
void SendSystem::initialize(DataParser *dataParser, QMutex *globalMutex)
|
|
{
|
|
qDebug() << "SendSystem::initialize thread ID " << QThread::currentThreadId();
|
|
|
|
this->dataParser = dataParser;
|
|
this->globalMutex = globalMutex;
|
|
|
|
connect(this, &SendSystem::sigSendNotify, dataParser->ClientAnswer(), &ClientAnswerParser::notify, Qt::DirectConnection); //потому что возвращает значение
|
|
}
|
|
|
|
void SendSystem::setClient(Client *client, QTcpSocket *socket)
|
|
{
|
|
qDebug() << "SendSystem::setClient thread ID " << QThread::currentThreadId();
|
|
|
|
this->socket = socket;
|
|
this->client = client;
|
|
|
|
this->type = client->getClientType();
|
|
|
|
flSendingStopped = false;
|
|
}
|
|
|
|
void SendSystem::updateFiles(QList<FileData> fileSendList, QList<FileData> deleteList)
|
|
{
|
|
QListIterator<FileData> clientIterator(deleteList);
|
|
|
|
while(clientIterator.hasNext())
|
|
{
|
|
FileData data = clientIterator.next();
|
|
|
|
slot_sendDeleteBlock(data.path);
|
|
if(slot_getIsSendingStopped())
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " isSendStopped", LogLevel::ERROR);
|
|
return;
|
|
}
|
|
}
|
|
|
|
QListIterator<FileData> serverIterator(fileSendList);
|
|
|
|
while(serverIterator.hasNext())
|
|
{
|
|
FileData data = serverIterator.next();
|
|
|
|
if (data.hash == "FOLDER")
|
|
{
|
|
slot_sendFolderBlock(data.path);
|
|
}
|
|
else
|
|
{
|
|
slot_sendFileBlock_forQtClient(data.path);
|
|
}
|
|
|
|
if(slot_getIsSendingStopped())
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
slot_sendPacketType(PacketType::UPDATE_FILES_COMPLETE);
|
|
}
|
|
|
|
bool SendSystem::waitWrittenData(QString marker, int msec)
|
|
{
|
|
bool success = socket->waitForBytesWritten(msec);
|
|
if(success)
|
|
{
|
|
//qInfo() << "Data sended OK. <" + marker + ">";
|
|
}
|
|
else
|
|
{
|
|
qDebug() << "WaitForBytesWritten timeout. <" + marker + ">";
|
|
}
|
|
return success;
|
|
}
|
|
|
|
|
|
void SendSystem::slot_BytesWrittenToSocket(qint64 bytes)
|
|
{
|
|
flWaitWritenToSocket = false;
|
|
bytesWritedToSocket = bytes;
|
|
}
|
|
|
|
bool SendSystem::slot_getIsSendingStopped() const
|
|
{
|
|
return flSendingStopped;
|
|
}
|
|
|
|
void SendSystem::slot_stopSending()
|
|
{
|
|
flSendingStopped = true;
|
|
}
|
|
|
|
void SendSystem::slot_socketClose()
|
|
{
|
|
socket->close();
|
|
}
|
|
|
|
|
|
void SendSystem::slot_sendVersion()
|
|
{
|
|
QByteArray data = dataParser->ClientAnswer()->currentVersion();
|
|
slot_sendXmlAnswer(data);
|
|
}
|
|
|
|
void SendSystem::slot_sendNotify(QString notify)
|
|
{
|
|
auto answer = emit sigSendNotify(notify);
|
|
slot_sendXmlAnswer(answer);
|
|
}
|
|
|
|
void SendSystem::slot_sendPacketType(PacketType packetType)
|
|
{
|
|
Logger::instance().log(" SEND TO: " + client->getLogin() + " " + enumToString(packetType), LogLevel::DEBUG);
|
|
if (client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
|
|
client->getClientType() == TypeClientAutorization::TYPE_GUI)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
stream << packetType;
|
|
|
|
waitWrittenData("sendPacketType");
|
|
}
|
|
else
|
|
{
|
|
QByteArray message;
|
|
int type = (int)packetType;
|
|
message.append(reinterpret_cast<char*>(&type), sizeof(int));
|
|
socket->write(message);
|
|
}
|
|
}
|
|
|
|
void SendSystem::slot_sendXmlAnswer(QByteArray array, PacketType packetType)
|
|
{
|
|
Logger::instance().log("SEND TO: "+ client->getLogin() + " " + enumToString(packetType) + "\n Text: " +
|
|
QString(array), LogLevel::DEBUG);
|
|
|
|
if (client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
|
|
client->getClientType() == TypeClientAutorization::TYPE_GUI)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
stream << packetType;
|
|
stream << array;
|
|
|
|
waitWrittenData("sendXmlAnswer");
|
|
}
|
|
else
|
|
{
|
|
slot_sendPacketType(packetType);
|
|
QByteArray message;
|
|
int size = array.length();
|
|
message.append(reinterpret_cast<char*>(&size), sizeof(int));
|
|
socket->write(message);
|
|
socket->write(array);
|
|
}
|
|
}
|
|
|
|
void SendSystem::slot_sendDocs_forQtClient(QString docsPath)
|
|
{
|
|
slot_sendFileBlock_forQtClient(docsPath);
|
|
}
|
|
|
|
void SendSystem::slot_sendNeedUpdate(bool flag, quint64 size, quint64 fileCount, quint64 deleteCount)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
stream << PacketType::TYPE_NEEDUPDATE;
|
|
stream << flag;
|
|
stream << size;
|
|
stream << fileCount;
|
|
stream << deleteCount;
|
|
|
|
waitWrittenData("sendNeedUpdate");
|
|
}
|
|
|
|
void SendSystem::slot_sendFolderBlock(QString path)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
stream << PacketType::TYPE_FOLDER;
|
|
stream << path;
|
|
|
|
waitWrittenData("sendFolderBlock");
|
|
}
|
|
|
|
void SendSystem::slot_sendDeleteBlock(QString path)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
stream << PacketType::TYPE_DELETE;
|
|
stream << path;
|
|
|
|
waitWrittenData("sendDeleteBlock");
|
|
}
|
|
|
|
void SendSystem::slot_sendFileBlock_forGUI(QString path)
|
|
{
|
|
//qDebug() << "SendSystem::sendFileBlock path: " << path;
|
|
|
|
if(slot_getIsSendingStopped())
|
|
{ //Поведение на случай отключения клиента
|
|
Logger::instance().log("Client: " + client->getLogin() + " isSendingStopped", LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
QFile file(path);
|
|
QFileInfo fileInfo(file);
|
|
|
|
fileSize = file.size();
|
|
|
|
if (fileSize == 0)
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " ERROR! File zero size " + fileInfo.fileName(), LogLevel::ERROR);
|
|
Logger::instance().log(path, LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
if(!file.open(QFile::ReadOnly))
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " ERROR! File not open: " + fileInfo.fileName(), LogLevel::ERROR);
|
|
Logger::instance().log(path, LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
countSend = 0;
|
|
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
stream << PacketType::TYPE_FILE;
|
|
stream << path << fileSize;
|
|
|
|
waitWrittenData("sendFileBlock:header " + fileInfo.fileName());
|
|
|
|
while(!file.atEnd())
|
|
{
|
|
if(socket->state() == QAbstractSocket::UnconnectedState)
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " UnconnectedState", LogLevel::ERROR);
|
|
break;
|
|
}
|
|
|
|
QByteArray data = file.read(sendFileBlockSize);
|
|
stream << data;
|
|
|
|
waitWrittenData(QString("sendFileBlock:data (size %1) ").arg(data.size()) + fileInfo.fileName());
|
|
|
|
countSend++;
|
|
}
|
|
|
|
file.close();
|
|
countSend = 0;
|
|
}
|
|
|
|
void SendSystem::slot_sendFileBlock_forQtClient(QString path)
|
|
{
|
|
//qDebug() << "SendSystem::sendFileBlock path: " << path;
|
|
|
|
if(slot_getIsSendingStopped())
|
|
{ //Поведение на случай отключения клиента
|
|
Logger::instance().log("Client: " + client->getLogin() + " isSendingStopped", LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
QFile file(path);
|
|
QFileInfo fileInfo(file);
|
|
|
|
fileSize = file.size();
|
|
|
|
if (fileSize == 0)
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " ERROR! File zero size " + fileInfo.fileName(), LogLevel::ERROR);
|
|
Logger::instance().log(path, LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
if(!file.open(QFile::ReadOnly))
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " ERROR! File not open: " + fileInfo.fileName(), LogLevel::ERROR);
|
|
Logger::instance().log(path, LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
countSend = 0;
|
|
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
stream << PacketType::TYPE_FILE;
|
|
stream << path << fileSize;
|
|
|
|
waitWrittenData("sendFileBlock:header " + fileInfo.fileName());
|
|
|
|
connect(this->socket, &QTcpSocket::bytesWritten, this, &SendSystem::slot_BytesWrittenToSocket);
|
|
|
|
while(!file.atEnd())
|
|
{
|
|
if(socket->state() == QAbstractSocket::UnconnectedState)
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " UnconnectedState", LogLevel::ERROR);
|
|
break;
|
|
}
|
|
|
|
qint64 readBytes = file.read(buffer, sendFileBlockSize);
|
|
if(readBytes <= 0)
|
|
break;
|
|
|
|
flWaitWritenToSocket = true;
|
|
|
|
while(!socket->write(buffer, readBytes))
|
|
{
|
|
qCritical() << "socket->write ERROR. size " + QString::number(readBytes);
|
|
int i = 0;
|
|
i++;
|
|
}
|
|
while(flWaitWritenToSocket)
|
|
{
|
|
QCoreApplication::processEvents(); // Обеспечиваем обработку сообщений
|
|
int i = 0;
|
|
i++;
|
|
}
|
|
|
|
waitWrittenData(QString("sendFileBlock:data (readBytes %1, num %2) ").arg(QString::number(readBytes), QString::number(countSend)) + fileInfo.fileName());
|
|
|
|
countSend++;
|
|
}
|
|
|
|
disconnect(this->socket, &QTcpSocket::bytesWritten, this, &SendSystem::slot_BytesWrittenToSocket);
|
|
|
|
file.close();
|
|
countSend = 0;
|
|
}
|
|
|
|
void SendSystem::slot_sendFileBlockByteArray(QByteArray array, PacketType packetType)
|
|
{
|
|
if(client->getClientType() == TypeClientAutorization::TYPE_GUI)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
qint64 size = array.size();
|
|
qint64 bytesSended = 0;
|
|
|
|
if (size == 0)
|
|
{
|
|
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
stream << packetType; //Отправляем тип блока
|
|
stream << size;
|
|
|
|
waitWrittenData("sendFileBlockByteArray");
|
|
|
|
while (bytesSended < size)
|
|
{
|
|
QByteArray chunk = array.mid(bytesSended, sendFileBlockSize);
|
|
stream << chunk;
|
|
//bytesSended = socket->write(chunk);
|
|
|
|
waitWrittenData("sendFileBlockByteArray");
|
|
|
|
bytesSended += chunk.length();
|
|
}
|
|
}
|
|
else if(client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT)
|
|
{
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
qint64 size = array.size();
|
|
qint64 bytesSended = 0;
|
|
|
|
if (size == 0)
|
|
{
|
|
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
stream << packetType; //Отправляем тип блока
|
|
stream << size;
|
|
|
|
waitWrittenData("sendFileBlockByteArray");
|
|
|
|
while (bytesSended < size)
|
|
{
|
|
QByteArray chunk = array.mid(bytesSended, sendFileBlockSize);
|
|
//stream << chunk;
|
|
bytesSended = socket->write(chunk);
|
|
|
|
waitWrittenData("sendFileBlockByteArray");
|
|
|
|
bytesSended += chunk.length();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
slot_sendPacketType(packetType);
|
|
qint64 size = array.size();
|
|
qint64 bytesSended = 0;
|
|
|
|
if (size == 0)
|
|
{
|
|
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
QByteArray message;
|
|
message.append(reinterpret_cast<char*>(&size), sizeof(int));
|
|
socket->write(message);
|
|
|
|
while (size > 0)
|
|
{
|
|
QByteArray chunk = array.mid(bytesSended, sendFileBlockSize);
|
|
bytesSended = socket->write(chunk);
|
|
|
|
size -= bytesSended;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void SendSystem::slot_sendFileBlockWithRename_Hash_forQtClient(QString path, QString newName)
|
|
{
|
|
//qDebug() << "SendSystem::sendFileBlockWithRename thread ID " << QThread::currentThreadId();
|
|
|
|
if(slot_getIsSendingStopped())
|
|
{ //Поведение на случай отключения клиента
|
|
Logger::instance().log("Client: " + client->getLogin() + " isSendingStopped", LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
QFile file(Tools::createRootPath(path));
|
|
QFileInfo fileInfo(file);
|
|
fileSize = fileInfo.size();
|
|
|
|
if (fileSize == 0)
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " ERROR! File zero size " + fileInfo.fileName(), LogLevel::ERROR);
|
|
Logger::instance().log(path, LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
if(!file.open(QFile::ReadOnly))
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " ERROR! File not open: " + fileInfo.fileName(), LogLevel::ERROR);
|
|
Logger::instance().log(path, LogLevel::ERROR);
|
|
return;
|
|
}
|
|
|
|
QString pathForSend = Tools::createFolderPath(path) + "/" + staticDataFolderName + newName;
|
|
|
|
countSend = 0;
|
|
|
|
QDataStream stream(socket);
|
|
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
|
|
|
|
stream << PacketType::TYPE_FILE;
|
|
stream << pathForSend << fileSize;
|
|
|
|
waitWrittenData("sendFileBlockWithRename");
|
|
|
|
connect(this->socket, &QTcpSocket::bytesWritten, this, &SendSystem::slot_BytesWrittenToSocket);
|
|
|
|
while(!file.atEnd())
|
|
{
|
|
if(socket->state() == QAbstractSocket::UnconnectedState)
|
|
{
|
|
Logger::instance().log("Client: " + client->getLogin() + " UnconnectedState", LogLevel::ERROR);
|
|
break;
|
|
}
|
|
|
|
qint64 readBytes = file.read(buffer, sendFileBlockSize);
|
|
if(readBytes <= 0)
|
|
break;
|
|
|
|
flWaitWritenToSocket = true;
|
|
|
|
while(!socket->write(buffer, readBytes))
|
|
{
|
|
qCritical() << "socket->write ERROR. size " + QString::number(readBytes);
|
|
int i = 0;
|
|
i++;
|
|
}
|
|
while(flWaitWritenToSocket)
|
|
{
|
|
QCoreApplication::processEvents(); // Обеспечиваем обработку сообщений
|
|
int i = 0;
|
|
i++;
|
|
}
|
|
|
|
waitWrittenData(QString("sendFileBlock:data (readBytes %1, num %2) ").arg(QString::number(readBytes), QString::number(countSend)) + fileInfo.fileName());
|
|
|
|
countSend++;
|
|
}
|
|
|
|
disconnect(this->socket, &QTcpSocket::bytesWritten, this, &SendSystem::slot_BytesWrittenToSocket);
|
|
|
|
file.close();
|
|
countSend = 0;
|
|
//waitWrittenData("sendFileBlockWithRename");
|
|
//socket->waitForReadyRead(100);
|
|
|
|
slot_sendNotify(commandHashCompleteClient);
|
|
}
|