From a86981f8e1d969069ff1b813b504c0efb2d077e4 Mon Sep 17 00:00:00 2001 From: zhangsheng Date: Tue, 3 Feb 2026 20:31:37 +0800 Subject: [PATCH] modify ftp upload to scp --- BoardSetting.cpp | 72 ++----- ChannelList.cpp | 14 +- Configuration.cpp | 22 +- CopyDatFile.cpp | 223 +++++++++++-------- CopyDatFile.h | 20 +- DataWatch3500_GUI.pro | 17 +- FileServerConfig.cpp | 47 ++-- HistoryAlarm.cpp | 48 +++-- ImportConfig.cpp | 44 ++-- NTPServerConfig.cpp | 19 +- NetMgr.cpp | 22 +- NetMgr.h | 1 + OtherConfig.cpp | 16 +- RealTimeAlarm.cpp | 52 +++-- RealTimeAlarm.h | 2 +- TerminalInfo.cpp | 16 +- TriggerConfig.cpp | 22 +- UnitSetting.cpp | 15 +- WorkingCondition.cpp | 15 +- ftpclient.cpp | 36 ++-- mainwindow.cpp | 1 - realtimeform.cpp | 1 + scp_client.cpp | 491 ++++++++++++++++++++++++++++++++++++++++++ scp_client.h | 83 +++++++ 24 files changed, 1009 insertions(+), 290 deletions(-) create mode 100644 scp_client.cpp create mode 100644 scp_client.h diff --git a/BoardSetting.cpp b/BoardSetting.cpp index 1f82e26..33e34da 100644 --- a/BoardSetting.cpp +++ b/BoardSetting.cpp @@ -3,6 +3,7 @@ #include "global.h" #include #include "sqlitedb.h" +#include "scp_client.h" CBoardSetting::CBoardSetting(QWidget *parent) : QWidget(parent), @@ -480,12 +481,15 @@ void CBoardSetting::PushData() strTablename = "t_TriggerConfig"; g_SqliteDB->DeleteData(strTablename); - QString strURL = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitWorkConditionsInfo.json"); -// g_FtpClient->SetServerInfo(strURL); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileName,"UnitWorkConditionsInfo.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("UnitWorkConditionsInfo.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"UnitWorkConditionsInfo.json"); - g_FtpClient->uploadFile(strURL,fileName,"UnitWorkConditionsInfo.json"); QJsonDocument jsonDocUnit; QJsonObject UnitObj; UnitObj["NULL"] = ""; @@ -502,12 +506,9 @@ void CBoardSetting::PushData() fileUnit.open(QIODevice::WriteOnly); fileUnit.write(jsonDocUnit.toJson()); fileUnit.close(); - QString str2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations.json"); -// g_FtpClient->SetServerInfo(str2); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileNameUnit,"UnitConfigurations.json"); - g_FtpClient->uploadFile(str2,fileNameUnit,"UnitConfigurations.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitConfigurations.json"); + scp.upload(fileName, remotePath,"UnitConfigurations.json"); #ifdef Q_OS_WIN32 QString fileNameUnit2 = QCoreApplication::applicationDirPath() + "\\config\\UnitConfigurations2.json"; #endif @@ -520,12 +521,10 @@ void CBoardSetting::PushData() fileUnit2.open(QIODevice::WriteOnly); fileUnit2.write(jsonDocUnit.toJson()); fileUnit2.close(); - QString str22 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations2.json"); -// g_FtpClient->SetServerInfo(str22); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileNameUnit2,"UnitConfigurations2.json"); - g_FtpClient->uploadFile(str22,fileNameUnit2,"UnitConfigurations2.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitConfigurations2.json"); + scp.upload(fileName, remotePath,"UnitConfigurations2.json"); + g_channelSetting = g_SqliteDB->GetDataMultiLine("t_ChannelSetting"); for (int i = 0; i < g_channelSetting.size(); i++) @@ -577,12 +576,8 @@ void CBoardSetting::PushData() fileTri.open(QIODevice::WriteOnly); fileTri.write(jsonDocTri.toJson()); fileTri.close(); - QString str1 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings.json"); -// g_FtpClient->SetServerInfo(str1); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileNameTri,"TriggerSettings.json"); - - g_FtpClient->uploadFile(str1,fileNameTri,"TriggerSettings.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerSettings.json"); + scp.upload(fileName, remotePath,"TriggerSettings.json"); #ifdef Q_OS_WIN32 QString fileNameTri2 = QCoreApplication::applicationDirPath() + "\\config\\TriggerSettings2.json"; @@ -595,17 +590,12 @@ void CBoardSetting::PushData() fileTri2.open(QIODevice::WriteOnly); fileTri2.write(jsonDocTri.toJson()); fileTri2.close(); - QString strTri2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings2.json"); -// g_FtpClient->SetServerInfo(strTri2); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileNameTri2,"TriggerSettings2.json"); - g_FtpClient->uploadFile(strTri2,fileNameTri2,"TriggerSettings2.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerSettings2.json"); + scp.upload(fileName, remotePath,"TriggerSettings2.json"); - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitBoardsInfo.json"); -// g_FtpClient->SetServerInfo(str); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(name,"UnitBoardsInfo.json"); - g_FtpClient->uploadFile(str,name,"UnitBoardsInfo.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitBoardsInfo.json"); + scp.upload(fileName, remotePath,"UnitBoardsInfo.json"); + scp.disconnectFromHost(); disconnect(g_NetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); } @@ -929,10 +919,6 @@ void CBoardSetting::on_pushButton_Init_clicked() strTablename = "t_TriggerConfig"; g_SqliteDB->DeleteData(strTablename); -// QString strURL = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitWorkConditionsInfo.json"); -// g_FtpClient->SetServerInfo(strURL); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileName,"UnitWorkConditionsInfo.json"); customLogMessageHandler(QtDebugMsg,"初始化工况配置信息推送完成!"); QJsonDocument jsonDocUnit; QJsonObject UnitObj; @@ -949,10 +935,6 @@ void CBoardSetting::on_pushButton_Init_clicked() fileUnit.open(QIODevice::WriteOnly); fileUnit.write(jsonDocUnit.toJson()); fileUnit.close(); -// QString str2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations.json"); -// g_FtpClient->SetServerInfo(str2); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileNameUnit,"UnitConfigurations.json"); customLogMessageHandler(QtDebugMsg,"初始化机组配置信息推送完成!"); g_channelSetting = g_SqliteDB->GetDataMultiLine("t_ChannelSetting"); g_ChannelBaseInfo.clear(); @@ -1006,15 +988,7 @@ void CBoardSetting::on_pushButton_Init_clicked() fileTri.open(QIODevice::WriteOnly); fileTri.write(jsonDocTri.toJson()); fileTri.close(); -// QString str1 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings.json"); -// g_FtpClient->SetServerInfo(str1); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(fileNameTri,"TriggerSettings.json"); -// QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitBoardsInfo.json"); -// g_FtpClient->SetServerInfo(str); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(name,"UnitBoardsInfo.json"); customLogMessageHandler(QtDebugMsg,"初始化机组板卡配置信息推送完成!"); #ifndef NO_FILTER QJsonObject sendData; @@ -1172,10 +1146,6 @@ void CBoardSetting::putJson() g_ChannelBaseInfo.append(tempchannelbaseinfo); } initReadConfig(); -// QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("ChannelSettings.json"); -// g_FtpClient->SetServerInfo(str); -// g_FtpClient->SetUserInfo("root","@#cidw!@123456"); -// g_FtpClient->UpLoadFile(name,"ChannelSettings.json"); customLogMessageHandler(QtDebugMsg,"初始化通道配置信息推送完成!"); disconnect(g_NetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); } diff --git a/ChannelList.cpp b/ChannelList.cpp index e5156bc..407293f 100644 --- a/ChannelList.cpp +++ b/ChannelList.cpp @@ -9,6 +9,7 @@ #include #include #include "NetMgr.h" +#include "scp_client.h" CChannelList::CChannelList(QWidget *parent) : QWidget(parent), @@ -519,10 +520,15 @@ void CChannelList::putJson() } initReadConfig(); #if QT_NO_DEBUG - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("ChannelSettings.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(name,"ChannelSettings.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("ChannelSettings.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(name, remotePath,"ChannelSettings.json"); + scp.disconnectFromHost(); #endif } diff --git a/Configuration.cpp b/Configuration.cpp index 21c222f..8b5e34f 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -4,7 +4,7 @@ #include #include #include - +#include "scp_client.h" CConfiguration::CConfiguration(QWidget *parent) : QWidget(parent), @@ -1024,15 +1024,17 @@ void CConfiguration::PushData() QString tableName = " t_UnitConfiguration "; g_SqliteDB->DeleteDataW(tableName,""); - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"UnitConfigurations.json"); - - QString str2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations2.json"); - g_FtpClient->SetServerInfo(str2); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName2,"UnitConfigurations2.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("UnitConfigurations.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"UnitConfigurations.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitConfigurations2.json"); + scp.upload(fileName, remotePath,"UnitConfigurations2.json"); + scp.disconnectFromHost(); } diff --git a/CopyDatFile.cpp b/CopyDatFile.cpp index 27934e6..fd6fc8c 100644 --- a/CopyDatFile.cpp +++ b/CopyDatFile.cpp @@ -3,7 +3,16 @@ #include #include "NetMgr.h" #include - +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#endif +static const QString kUpItem = "__UP__"; CCopyDatFile::CCopyDatFile(QWidget *parent) : QWidget(parent), ui(new Ui::CCopyDatFile) @@ -19,128 +28,166 @@ CCopyDatFile::CCopyDatFile(QWidget *parent) : ui->treeWidget_fileList->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(ui->treeWidget_fileList ,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(on_treeWidget_customContextMenuRequested(const QPoint &))); connect(ui->treeWidget_dist, &QTreeWidget::itemActivated,this, &CCopyDatFile::processItem); + connect(ui->treeWidget_fileList, &QTreeWidget::itemDoubleClicked, + this, &CCopyDatFile::onItemDoubleClicked); + ui->label_path->setText("/run/media/"); connectToFtp(); } CCopyDatFile::~CCopyDatFile() { + scp.disconnectFromHost(); delete ui; } void CCopyDatFile::connectToFtp() { - ftp = new QFtp(this); - ftp -> connectToHost(IP,21); - ftp -> login("root","@#cidw!@123456"); - connect(ftp, SIGNAL(commandFinished(int, bool)),this, SLOT(ftpCommandFinished(int, bool))); - connect(ftp, SIGNAL(listInfo(const QUrlInfo&)),this, SLOT(addToList(const QUrlInfo&))); - connect(ftp, SIGNAL(listInfo(const QUrlInfo&)),this, SLOT(addToDistList(const QUrlInfo&))); + bool res = scp.connectToHost("192.168.0.102", 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(this, QStringLiteral("提示"), "连接失败!"); + return; + } + QString path = "/opt/"; + + QVector files ; + scp.listRemoteDir(path,files); + + fillTreeWidget(ui->treeWidget_fileList, files, path); + + } void CCopyDatFile::ftpCommandFinished(int, bool error) { - qDebug() << ftp->currentCommand() <currentCommand() == QFtp::ConnectToHost) - { - if (error) { +// qDebug() << ftp->currentCommand() <currentCommand() == QFtp::ConnectToHost) +// { +// if (error) { - return; - } - else { +// return; +// } +// else { - return; - } - } +// return; +// } +// } - if (ftp->currentCommand() == QFtp::Login){ - qDebug() << "连接成功!" << endl; - ftp -> cd("/var/www/html/cidwdat/"); - ftp->list(); - } +// if (ftp->currentCommand() == QFtp::Login){ +// qDebug() << "连接成功!" << endl; +// ftp -> cd("/var/www/html/cidwdat/"); +// ftp->list(); +// } - if (ftp->currentCommand() == QFtp::Get) { - if (error) { +// if (ftp->currentCommand() == QFtp::Get) { +// if (error) { +// } else { + +// } + + +// } else if (ftp->currentCommand() == QFtp::List) { +// qDebug() << "List" << endl; +// } +} +static QString permToString(uint perm) +{ + QString s; + s += (perm & 0400) ? "r" : "-"; + s += (perm & 0200) ? "w" : "-"; + s += (perm & 0100) ? "x" : "-"; + s += (perm & 0040) ? "r" : "-"; + s += (perm & 0020) ? "w" : "-"; + s += (perm & 0010) ? "x" : "-"; + s += (perm & 0004) ? "r" : "-"; + s += (perm & 0002) ? "w" : "-"; + s += (perm & 0001) ? "x" : "-"; + return s; +} + +void CCopyDatFile::fillTreeWidget( + QTreeWidget *tree, + const QVector &files, + const QString ¤tPath) +{ + tree->clear(); + QTreeWidgetItem *up = new QTreeWidgetItem; + up->setText(ColName, ".."); + up->setText(ColType, "Dir"); + up->setIcon(ColName, QIcon(":/icons/up.png")); + //up->setData(ColName, Qt::UserRole, kUpItem); + ui->treeWidget_fileList->addTopLevelItem(up); + + for (const auto &f : files) { + + QTreeWidgetItem *item = new QTreeWidgetItem(tree); + + item->setText(ColName, f.name); + item->setText(ColSize, f.isDir ? "" : QString::number(f.size)); + item->setText(ColType, f.isDir ? "Dir" : "File"); + item->setText(ColPerm, permToString(f.permissions)); + item->setText(ColOwner, f.owner); + item->setText(ColGroup, f.group); + item->setText(ColModified, f.lastModified.toString("yyyy-MM-dd HH:mm:ss")); + item->setData(ColName, Qt::UserRole, f.name); + // 📁 目录加图标 + if (f.isDir) { + item->setIcon(ColName, + QApplication::style()->standardIcon(QStyle::SP_DirIcon)); + + // 标记可展开(即使还没加载) + item->setChildIndicatorPolicy( + QTreeWidgetItem::ShowIndicator); } else { - + item->setIcon(ColName, + QApplication::style()->standardIcon(QStyle::SP_FileIcon)); } + // 存远程完整路径(关键) + QString fullPath = currentPath; + if (!fullPath.endsWith('/')) + fullPath += '/'; + fullPath += f.name; - } else if (ftp->currentCommand() == QFtp::List) { - qDebug() << "List" << endl; - } -} -void CCopyDatFile::addToList(const QUrlInfo &urlInfo) -{ - QTreeWidgetItem *item = new QTreeWidgetItem; - - item->setText(0, urlInfo.name()); - item->setText(1, QString::number(urlInfo.size())); - item->setText(2, urlInfo.owner()); - item->setText(3, urlInfo.group()); - item->setText(4, urlInfo.lastModified().toString("yyyy-MM-dd HH:mm:ss").toLocal8Bit().data()); - - QPixmap pixmap(urlInfo.isDir() ? ":/images/images/dir.png" : ":/images/images/file.png"); - item->setIcon(0, pixmap); - item->setData(0, Qt::UserRole,urlInfo.name()); - isDirectory[urlInfo.name()] = urlInfo.isDir(); - this -> ui -> treeWidget_fileList->addTopLevelItem(item); - if (!this -> ui -> treeWidget_fileList->currentItem()) { - this -> ui -> treeWidget_fileList->setCurrentItem(this -> ui -> treeWidget_fileList->topLevelItem(0)); - this -> ui -> treeWidget_fileList->setEnabled(true); + item->setData(ColName, Qt::UserRole, fullPath); } } -void CCopyDatFile::addToDistList(const QUrlInfo &urlInfo) -{ - QTreeWidgetItem *item = new QTreeWidgetItem; - - item->setText(0, urlInfo.name()); - item->setText(1, QString::number(urlInfo.size())); - item->setText(2, urlInfo.owner()); - item->setText(3, urlInfo.group()); - item->setText(4, urlInfo.lastModified().toString("yyyy-MM-dd HH:mm:ss").toLocal8Bit().data()); - - QPixmap pixmap(urlInfo.isDir() ? ":/images/images/dir.png" : ":/images/images/file.png"); - item->setIcon(0, pixmap); - - isDirectory[urlInfo.name()] = urlInfo.isDir(); - this -> ui -> treeWidget_dist->addTopLevelItem(item); - if (!this -> ui -> treeWidget_dist->currentItem()) { - this -> ui -> treeWidget_dist->setCurrentItem(this -> ui -> treeWidget_dist->topLevelItem(0)); - this -> ui -> treeWidget_dist->setEnabled(true); - } -} void CCopyDatFile::on_pushButton_refresh_clicked() { - disconnect(ftp, SIGNAL(listInfo(const QUrlInfo&)),this, SLOT(addToList(const QUrlInfo&))); + QString path = "/opt/"; + + QVector files ; + scp.listRemoteDir(path,files); + + fillTreeWidget(ui->treeWidget_dist, files, path); + + QString path_dist = "/run/media"; + + +} +void CCopyDatFile::onItemDoubleClicked(QTreeWidgetItem *item, int column) +{ + if (item->text(ColType) != "Dir") + return; + + QString path = item->data(ColName, Qt::UserRole).toString(); + + QVector files ; + scp.listRemoteDir(path,files); + + fillTreeWidget(ui->treeWidget_fileList, files, path); + + ui->treeWidget_fileList->setProperty("currentPath", path); + ui->label_path->setText(path); + - ui -> treeWidget_dist ->clear(); - ftp -> cd("/run/media/"); - ui->label_path->setText("/run/media/"); - m_strDistPath = ""; - m_strDistPath = "/run/media/"; - ftp->list(); } void CCopyDatFile::processItem(QTreeWidgetItem *item, int /*column*/) { - QString name = item->text(0); - if (isDirectory.value(name)) { - this -> ui -> treeWidget_dist->clear(); - isDirectory.clear(); - currentPath += '/'; - currentPath += name; - ftp->cd(name); - m_strDistPath = ""; - m_strDistPath = "/run/media" + currentPath; - ui->label_path->setText(m_strDistPath); - currentPath = ""; - ftp->list(); - return; - } } diff --git a/CopyDatFile.h b/CopyDatFile.h index b2a9306..e61f0d4 100644 --- a/CopyDatFile.h +++ b/CopyDatFile.h @@ -9,10 +9,21 @@ #include #include #include "global.h" +#include "scp_client.h" namespace Ui { class CCopyDatFile; } +enum Columns { + ColName = 0, + ColSize, + ColType, + ColPerm, + ColOwner, + ColGroup, + ColModified, + ColCount +}; class CCopyDatFile : public QWidget { @@ -27,14 +38,16 @@ private slots: //void cancelDownload(); void ftpCommandFinished(int commandId, bool error); - void addToList(const QUrlInfo &urlInfo); - void addToDistList(const QUrlInfo &urlInfo); void on_pushButton_refresh_clicked(); void processItem(QTreeWidgetItem *item, int column); void on_treeWidget_customContextMenuRequested(const QPoint &pos); void slotCopyItem(); void on_pushButton_exit_clicked(); - + void onItemDoubleClicked(QTreeWidgetItem *item, int column); + void fillTreeWidget( + QTreeWidget *tree, + const QVector &files, + const QString ¤tPath); private: Ui::CCopyDatFile *ui; QHash isDirectory; @@ -44,6 +57,7 @@ private: QString currentPath; QString m_strDistPath; QAction *copyAction; + ScpClient scp; }; #endif // COPYDATFILE_H diff --git a/DataWatch3500_GUI.pro b/DataWatch3500_GUI.pro index 049261d..8a07c5e 100644 --- a/DataWatch3500_GUI.pro +++ b/DataWatch3500_GUI.pro @@ -6,11 +6,11 @@ QT += core gui network charts -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets sql ftp printsupport +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets sql printsupport TARGET = DataWatch3500_GUI TEMPLATE = app - +win32:CONFIG += console # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the @@ -76,6 +76,7 @@ SOURCES += \ BoardSetting.cpp \ UnitSetting.cpp \ WorkingCondition.cpp \ + scp_client.cpp \ sqlitedb.cpp HEADERS += \ @@ -129,6 +130,7 @@ HEADERS += \ BoardSetting.h \ UnitSetting.h \ WorkingCondition.h \ + scp_client.h \ sqlitedb.h \ utils_global.h @@ -182,7 +184,8 @@ DISTFILES += \ INCLUDEPATH += $$PWD/include/mqtt INCLUDEPATH += $$PWD/include/fftw - +INCLUDEPATH += $$PWD/include/libssh2 +INCLUDEPATH += $$PWD/include/openssl win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/fftw/ -llibfftw3-3 -llibfftw3f-3 -llibfftw3l-3 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/fftw/ -llibfftw3-3 -llibfftw3f-3 -llibfftw3l-3 @@ -191,3 +194,11 @@ else:unix: LIBS += -L$$PWD/lib/fftw/ -lfftw3 win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/mqtt/ -lQt5Qmqtt else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/mqtt/ -lQt5Qmqttd else:unix: LIBS += -L$$PWD/lib/mqtt/ -lQt5Qmqtt + +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/openssl/ -lssl -lcrypto -lws2_32 +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/openssl/ -lssl -lcrypto -lws2_32 +else:unix: LIBS += -L$$PWD/lib/openssl/linux -lssl -lcrypto + +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/libssh2/ -lssh2 +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/libssh2/ -lssh2 +else:unix: LIBS += -L$$PWD/lib/libssh2/linux -lssh2 diff --git a/FileServerConfig.cpp b/FileServerConfig.cpp index 1519d39..ce3480c 100644 --- a/FileServerConfig.cpp +++ b/FileServerConfig.cpp @@ -1,6 +1,7 @@ #include "FileServerConfig.h" #include "ui_FileServerConfig.h" #include "NetMgr.h" +#include "scp_client.h" CFileServerConfig::CFileServerConfig(QWidget *parent) : QWidget(parent), @@ -224,10 +225,14 @@ void CFileServerConfig::on_pushButtonPush_clicked() file.write(jsonDoc.toJson()); file.close(); - QString str2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("NetWorkConfig.json"); - g_FtpClient->SetServerInfo(str2); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"NetWorkConfig.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("NetWorkConfig.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"NetWorkConfig.json"); QJsonObject tempObj,OptionObj; OptionObj["localServerIpAddress"] = ui->lineEdit_ServerIP->text(); @@ -254,10 +259,9 @@ void CFileServerConfig::on_pushButtonPush_clicked() file2.write(jsonDoc.toJson()); file2.close(); - QString str3 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("ServerConfig.json"); - g_FtpClient->SetServerInfo(str3); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"ServerConfig.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("ServerConfig.json"); + scp.upload(fileName, remotePath,"ServerConfig.json"); + scp.disconnectFromHost(); } void CFileServerConfig::slotNetMgr(QString sAddr, const QVariant &msg) @@ -346,11 +350,15 @@ void CFileServerConfig::on_pushButtonConfirm_clicked() file.open(QIODevice::WriteOnly); file.write(jsonDoc.toJson()); file.close(); - - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TcpConfig.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"TcpConfig.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("TcpConfig.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"TcpConfig.json"); + scp.disconnectFromHost(); } @@ -375,9 +383,14 @@ void CFileServerConfig::on_pushButtonConfirm2_clicked() file.write(jsonDoc.toJson()); file.close(); - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("ModbusConfig.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"ModbusConfig.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("ModbusConfig.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"ModbusConfig.json"); + scp.disconnectFromHost(); } diff --git a/HistoryAlarm.cpp b/HistoryAlarm.cpp index 6da7b7a..b7d4531 100644 --- a/HistoryAlarm.cpp +++ b/HistoryAlarm.cpp @@ -7,6 +7,7 @@ #include "ftpclient.h" #include "global.h" #include "NetMgr.h" +#include "scp_client.h" CHistoryAlarm::CHistoryAlarm(QWidget *parent) : QWidget(parent), @@ -552,13 +553,16 @@ void CHistoryAlarm::OpenDatFile(QString& strFileName) void CHistoryAlarm::downloadProcess_Slot(qint64 byteSend, qint64 byteTotal) { qDebug() << byteSend << byteTotal << endl; - downloadProgressDialog->setRange(0, byteTotal); - downloadProgressDialog->setValue(byteSend); - if(byteSend == byteTotal){ - disconnect(g_FtpClient,SIGNAL(sigDownloadProcess(qint64 , qint64 )),this,SLOT(downloadProcess_Slot(qint64 , qint64))); - customLogMessageHandler(QtDebugMsg,"HistoryAlarm Open:" + g_LocalFile); - OpenDatFile(g_LocalFile); + if (byteTotal <= 0) return; + if (!downloadProgressDialog || downloadProgressDialog->wasCanceled()) { + return; } + if (downloadProgressDialog->maximum() != byteTotal) { + downloadProgressDialog->setRange(0, byteTotal); + } + downloadProgressDialog->setValue(byteSend); + int percent = (double)byteSend / byteTotal * 100.0; + downloadProgressDialog->setLabelText(tr("正在下载... %1%").arg(percent)); } void CHistoryAlarm::Details(const QModelIndex &index) @@ -585,20 +589,30 @@ void CHistoryAlarm::Details(const QModelIndex &index) if(file.exists()){ OpenDatFile(strPath); }else{ + downloadProgressDialog = new QProgressDialog(this); - downloadProgressDialog->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); + downloadProgressDialog->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::CustomizeWindowHint); downloadProgressDialog->setWindowModality(Qt::WindowModal); - downloadProgressDialog->setWindowTitle(tr("Please Wait")); - downloadProgressDialog->setLabelText(tr("下载中...")); - //downloadProgressDialog->setCancelButton(0); + downloadProgressDialog->setLabelText(tr("正在下载... 0%")); + downloadProgressDialog->setCancelButtonText(tr("取消")); downloadProgressDialog->show(); - qDebug() << "file2" << endl; - connect(g_FtpClient,SIGNAL(sigDownloadProcess(qint64 , qint64 )),this,SLOT(downloadProcess_Slot(qint64 , qint64))); - //connect(g_FtpClient,SIGNAL(sigDownloadStatus()),this,SLOT(DownloadStatus_Slot())); - QString str = QString("ftp://%1/").arg(IP); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->DownLoad(strFileName,strPath); + if(this->isVisible()){ + int x = this->geometry().center().x() - downloadProgressDialog->width() / 2; + int y = this->geometry().center().y() - downloadProgressDialog->height() / 2; + downloadProgressDialog->move(x, y); + } + ScpClient scp; + connect(downloadProgressDialog, &QProgressDialog::canceled, [&scp]() { + // 执行停止下载的操作 + scp.cancel(); + qDebug() << "Download task canceled by user."; + }); + connect(&scp, SIGNAL(progress(qint64 , qint64 )), this,SLOT(downloadProcess_Slot(qint64 , qint64 ))); + connect(&scp, SIGNAL(error(const QString &)), this,SLOT(downloadError_Slot(const QString &))); + connect(&scp, SIGNAL(finished()), this,SLOT(downloadFinished_Slot())); + scp.connectToHost(IP, 22, "root", "cidw!@123456"); + scp.download(strFileName, strPath); + qDebug() << "filename_list" << strPath; } } diff --git a/ImportConfig.cpp b/ImportConfig.cpp index e49d571..22d6143 100644 --- a/ImportConfig.cpp +++ b/ImportConfig.cpp @@ -3,6 +3,7 @@ #include #include #include "sqlitedb.h" +#include "scp_client.h" CImportConfig::CImportConfig(QWidget *parent) : QWidget(parent), @@ -172,6 +173,14 @@ void CImportConfig::on_pushButton_confirm_clicked() copyDir2.removeRecursively(); } + QString remotePath = ""; + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + #ifdef Q_OS_WIN32 QString fileNameInfo = QCoreApplication::applicationDirPath() + "\\config\\UnitWorkConditionsInfo.json"; @@ -180,9 +189,8 @@ void CImportConfig::on_pushButton_confirm_clicked() QString fileNameInfo = QCoreApplication::applicationDirPath() + "/config/UnitWorkConditionsInfo.json"; #endif - QString strURL = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitWorkConditionsInfo.json"); - - g_FtpClient->uploadFile(strURL,fileNameInfo,"UnitWorkConditionsInfo.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitWorkConditionsInfo.json"); + scp.upload(fileNameInfo, remotePath,"UnitWorkConditionsInfo.json"); @@ -192,10 +200,10 @@ void CImportConfig::on_pushButton_confirm_clicked() #ifdef Q_OS_LINUX QString fileNameUnit = QCoreApplication::applicationDirPath() + "/config/UnitConfigurations.json"; #endif + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitConfigurations.json"); + scp.upload(fileNameUnit, remotePath,"UnitConfigurations.json"); - QString str2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations.json"); - g_FtpClient->uploadFile(str2,fileNameUnit,"UnitConfigurations.json"); #ifdef Q_OS_WIN32 QString fileNameUnit2 = QCoreApplication::applicationDirPath() + "\\config\\UnitConfigurations2.json"; #endif @@ -203,9 +211,8 @@ void CImportConfig::on_pushButton_confirm_clicked() QString fileNameUnit2 = QCoreApplication::applicationDirPath() + "/config/UnitConfigurations2.json"; #endif - QString str22 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitConfigurations2.json"); - - g_FtpClient->uploadFile(str22,fileNameUnit2,"UnitConfigurations2.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitConfigurations2.json"); + scp.upload(fileNameUnit2, remotePath,"UnitConfigurations2.json"); #ifdef Q_OS_WIN32 QString fileNameTri = QCoreApplication::applicationDirPath() + "\\config\\TriggerSettings.json"; @@ -213,10 +220,8 @@ void CImportConfig::on_pushButton_confirm_clicked() #ifdef Q_OS_LINUX QString fileNameTri = QCoreApplication::applicationDirPath() + "/config/TriggerSettings.json"; #endif - - QString str1 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings.json"); - - g_FtpClient->uploadFile(str1,fileNameTri,"TriggerSettings.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerSettings.json"); + scp.upload(fileNameTri, remotePath,"TriggerSettings.json"); #ifdef Q_OS_WIN32 QString fileNameTri2 = QCoreApplication::applicationDirPath() + "\\config\\TriggerSettings2.json"; @@ -225,9 +230,8 @@ void CImportConfig::on_pushButton_confirm_clicked() QString fileNameTri2 = QCoreApplication::applicationDirPath() + "/config/TriggerSettings2.json"; #endif - QString strTri2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings2.json"); - - g_FtpClient->uploadFile(strTri2,fileNameTri2,"TriggerSettings2.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerSettings2.json"); + scp.upload(fileNameTri2, remotePath,"TriggerSettings2.json"); #ifdef Q_OS_WIN32 QString name = QCoreApplication::applicationDirPath() + "\\config\\UnitBoardsInfo.json"; @@ -235,9 +239,8 @@ void CImportConfig::on_pushButton_confirm_clicked() #ifdef Q_OS_LINUX QString name = QCoreApplication::applicationDirPath() + "/config/UnitBoardsInfo.json"; #endif - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitBoardsInfo.json"); - - g_FtpClient->uploadFile(str,name,"UnitBoardsInfo.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitBoardsInfo.json"); + scp.upload(name, remotePath,"UnitBoardsInfo.json"); #ifdef Q_OS_WIN32 QString fileNameChannel = QCoreApplication::applicationDirPath() + "\\config\\ChannelSettings.json"; @@ -245,9 +248,10 @@ void CImportConfig::on_pushButton_confirm_clicked() #ifdef Q_OS_LINUX QString fileNameChannel = QCoreApplication::applicationDirPath() + "/config/ChannelSettings.json"; #endif - QString strChannelSettings = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("ChannelSettings.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("ChannelSettings.json"); + scp.upload(fileNameChannel, remotePath,"ChannelSettings.json"); - g_FtpClient->uploadFile(strChannelSettings,fileNameChannel,"ChannelSettings.json"); + scp.disconnectFromHost(); qApp->exit(0); QProcess::startDetached(qApp->applicationFilePath(), QStringList()); diff --git a/NTPServerConfig.cpp b/NTPServerConfig.cpp index 2cc90c4..f14c2dc 100644 --- a/NTPServerConfig.cpp +++ b/NTPServerConfig.cpp @@ -3,7 +3,7 @@ #include "NetMgr.h" #include #include -#include "ftpclient.h" +#include "scp_client.h" CNTPServerConfig::CNTPServerConfig(QWidget *parent) : QWidget(parent), @@ -154,11 +154,18 @@ void CNTPServerConfig::slotReplyStatus(int result) file.write(jsonDoc.toJson()); file.close(); } + disconnect(g_NetMgr,SIGNAL(sigReplyStatus(int)), this, SLOT(slotReplyStatus(int))); } void CNTPServerConfig::on_radioButton_switch_clicked() { - connect(g_FtpClient, SIGNAL(sigReplyStatus(int)), this, SLOT(slotReplyStatus(int))); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + connect(g_NetMgr, SIGNAL(sigReplyStatus(int)), this, SLOT(slotReplyStatus(int))); QJsonObject NTPServerObj,itemObj; itemObj["ntpNetworkStation"] = ui->lineEdit_NTP_IP->text(); @@ -187,11 +194,9 @@ void CNTPServerConfig::on_radioButton_switch_clicked() file.open(QIODevice::WriteOnly); file.write(jsonDoc.toJson()); file.close(); - - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("ServerConfig.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"ServerConfig.json",4); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("ServerConfig.json"); + scp.upload(fileName, remotePath,"ServerConfig.json",4); + scp.disconnectFromHost(); } diff --git a/NetMgr.cpp b/NetMgr.cpp index d29e624..ed7fef5 100644 --- a/NetMgr.cpp +++ b/NetMgr.cpp @@ -17,6 +17,7 @@ #include #include "log.h" #include "global.h" +#include enum{ HTTP_CMD_ID = QNetworkRequest::User+100, @@ -343,13 +344,32 @@ void NetMgr::httpFinished(QNetworkReply *reply) void NetMgr::parseData(const QByteArray &szData, const QString &sUrlPath, QString sAddr) { - //qDebug() << sUrlPath << szData; + qDebug() << sUrlPath << szData; QJsonDocument doc = QJsonDocument::fromJson(szData); QJsonObject obj = doc.object(); QVariant var; var.setValue(obj); customLogMessageHandler(QtDebugMsg,QString(QJsonDocument(obj).toJson())); emit sigNetMgr(sAddr, var); + QJsonObject objec = var.value(); + qDebug() << objec; + if(objec.contains("cmd")) + { + QJsonValue arrays_value = objec.take("cmd"); + qDebug()<<"cmd ="< #include #include -#include "ftpclient.h" +#include +#include "scp_client.h" COtherConfig::COtherConfig(QWidget *parent) : QWidget(parent), @@ -240,10 +241,15 @@ void COtherConfig::on_pushButto_Trigger_clicked() file.write(jsonDoc.toJson()); file.close(); } - QString strURL = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerConfig.json"); - g_FtpClient->SetServerInfo(strURL); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"TriggerConfig.json"); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerConfig.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"TriggerConfig.json"); + scp.disconnectFromHost(); } QString COtherConfig::GBK2UTF8(QByteArray inStr) { diff --git a/RealTimeAlarm.cpp b/RealTimeAlarm.cpp index 806ef50..54732bc 100644 --- a/RealTimeAlarm.cpp +++ b/RealTimeAlarm.cpp @@ -5,7 +5,7 @@ #include "AlarmDetails.h" #include "sqlitedb.h" #include -#include "ftpclient.h" +#include "scp_client.h" CRealTimeAlarm::CRealTimeAlarm(QWidget *parent) : @@ -500,20 +500,22 @@ void CRealTimeAlarm::OpenDatFile(QString& strFileName) } DateViewdialog->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); } -void CRealTimeAlarm::DownloadStatus_Slot() +void CRealTimeAlarm::downloadFinished_Slot() { OpenDatFile(g_LocalFile); - disconnect(g_FtpClient,SIGNAL(sigDownloadProcess(qint64 , qint64 )),this,SLOT(downloadProcess_Slot(qint64 , qint64))); - disconnect(g_FtpClient,SIGNAL(sigDownloadStatus()),this,SLOT(DownloadStatus_Slot())); } void CRealTimeAlarm::downloadProcess_Slot(qint64 byteSend, qint64 byteTotal) { - downloadProgressDialog->setRange(0, byteTotal); - downloadProgressDialog->setValue(byteSend); - if(byteSend == byteTotal){ - disconnect(g_FtpClient,SIGNAL(sigDownloadProcess(qint64 , qint64 )),this,SLOT(downloadProcess_Slot(qint64 , qint64))); - OpenDatFile(g_LocalFile); + if (byteTotal <= 0) return; + if (!downloadProgressDialog || downloadProgressDialog->wasCanceled()) { + return; } + if (downloadProgressDialog->maximum() != byteTotal) { + downloadProgressDialog->setRange(0, byteTotal); + } + downloadProgressDialog->setValue(byteSend); + int percent = (double)byteSend / byteTotal * 100.0; + downloadProgressDialog->setLabelText(tr("正在下载... %1%").arg(percent)); } void CRealTimeAlarm::Details(const QModelIndex &index) @@ -541,20 +543,30 @@ void CRealTimeAlarm::Details(const QModelIndex &index) qDebug() << "file1" << endl; OpenDatFile(strPath); }else{ + downloadProgressDialog = new QProgressDialog(this); - downloadProgressDialog->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); + downloadProgressDialog->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::CustomizeWindowHint); downloadProgressDialog->setWindowModality(Qt::WindowModal); - downloadProgressDialog->setWindowTitle(tr("Please Wait")); - downloadProgressDialog->setLabelText(tr("下载中...")); - //downloadProgressDialog->setCancelButton(0); + downloadProgressDialog->setLabelText(tr("正在下载... 0%")); + downloadProgressDialog->setCancelButtonText(tr("取消")); downloadProgressDialog->show(); - qDebug() << "file2" << endl; - connect(g_FtpClient,SIGNAL(sigDownloadProcess(qint64 , qint64 )),this,SLOT(downloadProcess_Slot(qint64 , qint64))); - //connect(g_FtpClient,SIGNAL(sigDownloadStatus()),this,SLOT(DownloadStatus_Slot())); - QString str = QString("ftp://%1/").arg(IP); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->DownLoad(strFileName,strPath); + if(this->isVisible()){ + int x = this->geometry().center().x() - downloadProgressDialog->width() / 2; + int y = this->geometry().center().y() - downloadProgressDialog->height() / 2; + downloadProgressDialog->move(x, y); + } + ScpClient scp; + connect(downloadProgressDialog, &QProgressDialog::canceled, [&scp]() { + // 执行停止下载的操作 + scp.cancel(); + qDebug() << "Download task canceled by user."; + }); + connect(&scp, SIGNAL(progress(qint64 , qint64 )), this,SLOT(downloadProcess_Slot(qint64 , qint64 ))); + connect(&scp, SIGNAL(error(const QString &)), this,SLOT(downloadError_Slot(const QString &))); + connect(&scp, SIGNAL(finished()), this,SLOT(downloadFinished_Slot())); + scp.connectToHost(IP, 22, "root", "cidw!@123456"); + scp.download(strFileName, strPath); + qDebug() << "filename_list" << strPath; } } diff --git a/RealTimeAlarm.h b/RealTimeAlarm.h index 981c6db..bc551a6 100644 --- a/RealTimeAlarm.h +++ b/RealTimeAlarm.h @@ -29,7 +29,7 @@ private slots: public slots: void downloadProcess_Slot(qint64 byteSend, qint64 byteTotal); - void DownloadStatus_Slot(); + void downloadFinished_Slot(); signals: void ItemCheckStateSignal(QString strID, bool bChecked); private: diff --git a/TerminalInfo.cpp b/TerminalInfo.cpp index 5faaf21..d3ea126 100644 --- a/TerminalInfo.cpp +++ b/TerminalInfo.cpp @@ -2,7 +2,7 @@ #include "ui_TerminalInfo.h" #include "NetMgr.h" #include -#include "ftpclient.h" +#include "scp_client.h" #include "CopyDatFile.h" #include "Backup.h" #include "ImportConfig.h" @@ -287,14 +287,20 @@ void CTerminalInfo::on_pushButton_Update_clicked() if(FileName.isEmpty()) return; - QString str = QString("ftp://%1/var/%2").arg(IP).arg(FileName); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); if(text == "系统") curIndex = 0; else if(text == "后端主程序") curIndex = 1; - g_FtpClient->UpLoadFile(filepath,FileName,curIndex); + + QString remotePath = QString("/var/%1").arg(FileName); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(this, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(filepath, remotePath,FileName,curIndex); + scp.disconnectFromHost(); } diff --git a/TriggerConfig.cpp b/TriggerConfig.cpp index 7953d38..1c9d292 100644 --- a/TriggerConfig.cpp +++ b/TriggerConfig.cpp @@ -4,6 +4,7 @@ #include #include "ftpclient.h" #include "ViewTriggerConfig.h" +#include "scp_client.h" CTriggerConfig::CTriggerConfig(QWidget *parent) : QWidget(parent), @@ -837,16 +838,17 @@ void CTriggerConfig::PushData() g_SqliteDB->GetTriggerConfig("t_TriggerConfig",""); - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"TriggerSettings.json"); - - QString str2 = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("TriggerSettings2.json"); - g_FtpClient->SetServerInfo(str2); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName2,"TriggerSettings2.json"); - + QString remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerSettings.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"TriggerSettings.json"); + remotePath = QString("/CIDW/qtconfig/%1").arg("TriggerSettings2.json"); + scp.upload(fileName, remotePath,"TriggerSettings2.json"); + scp.disconnectFromHost(); disconnect(g_NetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); diff --git a/UnitSetting.cpp b/UnitSetting.cpp index 54c142b..98ea784 100644 --- a/UnitSetting.cpp +++ b/UnitSetting.cpp @@ -3,6 +3,7 @@ #include "global.h" #include #include "ftpclient.h" +#include "scp_client.h" CUnitSetting::CUnitSetting(QWidget *parent) : QWidget(parent), @@ -316,10 +317,16 @@ void CUnitSetting::PushData() file.open(QIODevice::WriteOnly); file.write(jsonDoc.toJson()); file.close(); - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitParameters.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"UnitParameters.json"); + + QString remotePath = QString("/CIDW/qtconfig/%1").arg("UnitParameters.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"UnitParameters.json"); + scp.disconnectFromHost(); disconnect(g_NetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); } diff --git a/WorkingCondition.cpp b/WorkingCondition.cpp index c8c8d1e..95715d4 100644 --- a/WorkingCondition.cpp +++ b/WorkingCondition.cpp @@ -4,6 +4,7 @@ #include #include "NetMgr.h" #include "ftpclient.h" +#include "scp_client.h" CWorkingcondition::CWorkingcondition(QWidget *parent) : QWidget(parent), @@ -871,12 +872,16 @@ void CWorkingcondition::PushData() file.write(jsonDoc.toJson()); file.close(); - QString str = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitWorkConditionsInfo.json"); - g_FtpClient->SetServerInfo(str); - g_FtpClient->SetUserInfo("root","@#cidw!@123456"); - g_FtpClient->UpLoadFile(fileName,"UnitWorkConditionsInfo.json"); - disconnect(g_NetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); + QString remotePath = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitWorkConditionsInfo.json"); + + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(this, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(fileName, remotePath,"UnitWorkConditionsInfo.json"); } void CWorkingcondition::slotNetMgr(QString sAddr, const QVariant &msg) { diff --git a/ftpclient.cpp b/ftpclient.cpp index 12e6f75..dfa1196 100644 --- a/ftpclient.cpp +++ b/ftpclient.cpp @@ -46,24 +46,24 @@ void FtpClient::SetServerInfo(const QString fileAddr, int Port/* =21 */) void FtpClient::slotNetMgr(QString sAddr, const QVariant &msg) { - QJsonObject objec = msg.value(); - if(objec.contains("cmd")) - { - QJsonValue arrays_value = objec.take("cmd"); - qDebug()<<"cmd ="<(); +// if(objec.contains("cmd")) +// { +// QJsonValue arrays_value = objec.take("cmd"); +// qDebug()<<"cmd ="<OpenDataBase(); g_NetMgr = new NetMgr(this); - g_FtpClient = new FtpClient(); //读取ini diff --git a/realtimeform.cpp b/realtimeform.cpp index 9e9d3e3..c8e0806 100644 --- a/realtimeform.cpp +++ b/realtimeform.cpp @@ -1007,6 +1007,7 @@ void CRealTimeForm::LoadGraphicsConfig(int type) { pText->setData(4, key["static"].toString()); pText->setDefaultTextColor(QColor(31, 81, 136)); pText->setFont(font2); + pText->setPlainText("0.0"); } pItemGroup->addToGroup(pText); } diff --git a/scp_client.cpp b/scp_client.cpp new file mode 100644 index 0000000..c6cdb34 --- /dev/null +++ b/scp_client.cpp @@ -0,0 +1,491 @@ +#include "scp_client.h" +#include +#include +#ifdef Q_OS_UNIX +#include +#include +#endif +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#endif +#include "NetMgr.h" +#include +#include +#include +#include "global.h" + +ScpClient::ScpClient(QObject *parent) + : QObject(parent) +{ +#ifdef _WIN32 + WSADATA wsadata; + WSAStartup(MAKEWORD(2,2), &wsadata); +#endif + m_sock = -1; + m_session = nullptr; +} + +ScpClient::~ScpClient() +{ + disconnectFromHost(); +#ifdef _WIN32 + WSACleanup(); +#endif +} + +void ScpClient::cancel() +{ + m_cancelled.store(true); +} +bool ScpClient::connectToHost(const QString &host, + int port, + const QString &user, + const QString &password, + int timeoutMs) +{ + disconnectFromHost(); + + m_sock = socket(AF_INET, SOCK_STREAM, 0); + if (m_sock < 0) { + emit error("Failed to create socket"); + return false; + } + + struct sockaddr_in sin{}; + sin.sin_family = AF_INET; +#ifdef _WIN32 + sin.sin_addr.s_addr = inet_addr(host.toUtf8().constData()); +#else + if (inet_pton(AF_INET, host.toUtf8().constData(), &sin.sin_addr) <= 0) { + emit error("Invalid IP address"); + return false; + } +#endif + sin.sin_port = htons(port); + + if (::connect(m_sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) { + emit error("Failed to connect"); + return false; + } + + m_session = libssh2_session_init(); + if (!m_session) { + emit error("Failed to init libssh2 session"); + return false; + } + + // 阻塞模式 + libssh2_session_set_blocking(m_session, 1); + + if (libssh2_session_handshake(m_session, m_sock) != 0) { + emit error("Handshake failed"); + return false; + } + + if (libssh2_userauth_password( + m_session, + user.toUtf8().constData(), + password.toUtf8().constData()) != 0) + { + emit error("Authentication failed"); + return false; + } + + return true; +} + +void ScpClient::disconnectFromHost() +{ + m_cancelled.store(true); + if (m_session) { + libssh2_session_disconnect(m_session, "Bye"); + libssh2_session_free(m_session); + m_session = nullptr; + } + +#ifdef _WIN32 + if (m_sock != -1) closesocket(m_sock); +#else + if (m_sock != -1) close(m_sock); +#endif + m_sock = -1; +} + +bool ScpClient::download(const QString &remotePath, const QString &localPath) +{ + if (!m_session) return false; + m_cancelled.store(false); + + libssh2_struct_stat st; + // 使用 scp_recv2 获取远程文件信息 + LIBSSH2_CHANNEL* channel = libssh2_scp_recv2( + m_session, + remotePath.toUtf8().constData(), + &st); + + if (!channel) { + char *errmsg; + libssh2_session_last_error(m_session, &errmsg, nullptr, 0); + emit error(QString("SCP recv failed: %1").arg(errmsg)); + return false; + } + + QFile file(localPath); + if (!file.open(QIODevice::WriteOnly)) { + emit error("Open local file failed"); + libssh2_channel_free(channel); + return false; + } + + qint64 totalSize = st.st_size; + qint64 received = 0; + char buffer[16384]; // 使用 16KB 固定缓冲区 + + while (received < totalSize && !m_cancelled.load()) { + if (m_cancelled.load()) { + emit error("Download cancelled"); + break; + } + + // 计算剩余需要读取的字节数,防止溢出 + int toRead = sizeof(buffer); + if (totalSize - received < toRead) { + toRead = totalSize - received; + } + + ssize_t rc = libssh2_channel_read(channel, buffer, toRead); + + if (rc > 0) { + file.write(buffer, rc); + received += rc; + emit progress(received, totalSize); + } else if (rc < 0) { + emit error("Read error during download"); + break; + } else { + // rc == 0 意味着服务器提前关闭了流 + break; + } + } + + file.flush(); + file.close(); + + // 标准清理流程 + libssh2_channel_free(channel); + + if (!m_cancelled.load() && received != totalSize) { + emit error("File size mismatch (Incomplete download)"); + return false; + } + + emit finished(); + return received == totalSize; +} + +bool ScpClient::upload(const QString &localPath, + const QString &remotePath,const QString& fileName,int type, + int fileMode) +{ + if (!m_session) return false; + m_cancelled.store(false); + m_Type = type; + m_fileName = fileName; + QFile file(localPath); + if (!file.open(QIODevice::ReadOnly)) { + emit error("Open local file failed"); + return false; + } + + qint64 fileSize = file.size(); + qint64 sent = 0; + + LIBSSH2_CHANNEL* channel = libssh2_scp_send64( + m_session, + remotePath.toUtf8().constData(), + fileMode, + fileSize, + 0, 0); + if (!channel) { + emit error("SCP send failed"); + return false; + } + + char buffer[16384]; + while (sent < fileSize) { + if (m_cancelled.load()) { + emit error("Upload cancelled"); + break; + } + + qint64 n = file.read(buffer, sizeof(buffer)); + if (n <= 0) break; + + char* ptr = buffer; + while (n > 0) { + ssize_t rc = libssh2_channel_write(channel, ptr, n); + if (rc <= 0) { + emit error("Write failed"); + goto cleanup; + } + ptr += rc; + n -= rc; + sent += rc; + + emit progress(sent, fileSize); + if(sent == fileSize){ + uploadFinish(); + } + } + } + +cleanup: + libssh2_channel_send_eof(channel); + libssh2_channel_wait_eof(channel); + libssh2_channel_wait_closed(channel); + libssh2_channel_free(channel); + file.close(); + + emit finished(); + return sent == fileSize; +} +void ScpClient::uploadFinish(){ + if(m_fileName != ""){ + qDebug() << "uploadFinish" ; + QJsonObject allObj,cmdBody,temp; + QJsonArray tempArray; + if(m_fileName.contains(".json")){ + allObj.insert("cmd", "90"); + temp["fileName"] = m_fileName; + if(m_Type >= 0) + temp["content"] = m_Type; + tempArray.append(temp); + allObj.insert("cmdBody",tempArray); + }else{ + allObj.insert("cmd", "46"); + allObj.insert("type", m_Type); + temp["fileName"] = m_fileName; + allObj.insert("cmdBody",temp); + } + qDebug() << allObj << endl; + QNetworkRequest req; + QString sUrl = QString("http://%1/cgi-bin/General.cgi/").arg(IP); + req.setUrl(sUrl); + g_NetMgr->PostJson(req,allObj); + m_fileName = ""; + m_Type = -1; + } +} +QString ScpClient::uidToName(uint uid) +{ +#ifdef Q_OS_UNIX + struct passwd *pw = getpwuid(uid); + if (pw) + return QString::fromLocal8Bit(pw->pw_name); +#endif + return QString::number(uid); +} + +QString ScpClient::gidToName(uint gid) +{ +#ifdef Q_OS_UNIX + struct group *gr = getgrgid(gid); + if (gr) + return QString::fromLocal8Bit(gr->gr_name); + return QString::number(gid); +#endif + return QString::number(gid); + +} + +void ScpClient::waitSocket(SOCKET sock) +{ + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + + timeval tv; + tv.tv_sec = 10; + tv.tv_usec = 0; + + select(0, &fds, &fds, nullptr, &tv); +} + +bool ScpClient::listRemoteDir(const QString &path, + QVector &outList) +{ + outList.clear(); + + LIBSSH2_SFTP *sftp = nullptr; + + for (;;) { + sftp = libssh2_sftp_init(m_session); + if (sftp) + break; + + int err = libssh2_session_last_errno(m_session); + if (err == LIBSSH2_ERROR_EAGAIN) { + waitSocket(m_sock); // 必须 + continue; + } + + qDebug() << "sftp init failed:" << err; + return false; + } + + if (!sftp) { + emit error("sftp init failed"); + return false; + } + + LIBSSH2_SFTP_HANDLE *dir = + libssh2_sftp_opendir(sftp, path.toUtf8().constData()); + if (!dir) { + emit error("sftp opendir failed: " + path); + libssh2_sftp_shutdown(sftp); + return false; + } + + char filename[512]; + LIBSSH2_SFTP_ATTRIBUTES attrs; + + while (true) { + memset(&attrs, 0, sizeof(attrs)); + int rc = libssh2_sftp_readdir(dir, filename, sizeof(filename), &attrs); + if (rc <= 0) + break; + + QString name = QString::fromUtf8(filename); + if (name == "." || name == "..") + continue; + + RemoteFileInfo info; + info.name = name; + info.size = static_cast(attrs.filesize); + info.permissions = attrs.permissions; + info.isDir = LIBSSH2_SFTP_S_ISDIR(attrs.permissions); + + if (attrs.mtime) { + info.lastModified = + QDateTime::fromSecsSinceEpoch(attrs.mtime); + } + + info.uid = attrs.uid; + info.gid = attrs.gid; + info.owner = uidToName(attrs.uid); + info.group = gidToName(attrs.gid); + + outList.push_back(info); + } + + libssh2_sftp_closedir(dir); + libssh2_sftp_shutdown(sftp); + QString out; + if (exec("pwd", out)) + m_currentPath = out.trimmed(); + else + m_currentPath = "/"; + return true; +} + +bool ScpClient::makeRemoteDir(const QString &path, int mode) +{ + LIBSSH2_SFTP *sftp = libssh2_sftp_init(m_session); + if (!sftp) + return false; + + int rc = libssh2_sftp_mkdir( + sftp, path.toUtf8().constData(), mode); + + libssh2_sftp_shutdown(sftp); + return (rc == 0); +} +bool ScpClient::removeRemoteFile(const QString &path) +{ + LIBSSH2_SFTP *sftp = libssh2_sftp_init(m_session); + if (!sftp) + return false; + + int rc = libssh2_sftp_unlink( + sftp, path.toUtf8().constData()); + + libssh2_sftp_shutdown(sftp); + return (rc == 0); +} +bool ScpClient::removeRemoteDir(const QString &path) +{ + LIBSSH2_SFTP *sftp = libssh2_sftp_init(m_session); + if (!sftp) + return false; + + int rc = libssh2_sftp_rmdir( + sftp, path.toUtf8().constData()); + + libssh2_sftp_shutdown(sftp); + return (rc == 0); +} +bool ScpClient::renameRemote(const QString &oldPath, + const QString &newPath) +{ + LIBSSH2_SFTP *sftp = libssh2_sftp_init(m_session); + if (!sftp) + return false; + + int rc = libssh2_sftp_rename( + sftp, + oldPath.toUtf8().constData(), + newPath.toUtf8().constData()); + + libssh2_sftp_shutdown(sftp); + return (rc == 0); +} +bool ScpClient::exec(const QString &cmd, QString &output) +{ + LIBSSH2_CHANNEL *channel = libssh2_channel_open_session(m_session); + if (!channel) + return false; + + if (libssh2_channel_exec(channel, cmd.toUtf8().constData()) != 0) { + libssh2_channel_free(channel); + return false; + } + + char buffer[4096]; + for (;;) { + ssize_t n = libssh2_channel_read(channel, buffer, sizeof(buffer)); + if (n <= 0) + break; + output.append(QString::fromUtf8(buffer, n)); + } + + libssh2_channel_close(channel); + libssh2_channel_free(channel); + return true; +} +bool ScpClient::goUp() +{ + if (m_currentPath.isEmpty() || m_currentPath == "/") + return true; // 已经在根目录,仍返回 true + + int idx = m_currentPath.lastIndexOf('/'); + if (idx <= 0) { + m_currentPath = "/"; + } else { + m_currentPath = m_currentPath.left(idx); + } + + // 测试能否列出目录,确保路径有效 + QString dummy; + QString cmd = QString("ls -l %1").arg(m_currentPath); + if (!exec(cmd, dummy)) + return false; + + return true; +} + diff --git a/scp_client.h b/scp_client.h new file mode 100644 index 0000000..795e4d1 --- /dev/null +++ b/scp_client.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +#ifndef LIBSSH2_S_ISDIR +#define LIBSSH2_S_ISDIR(mode) (((mode) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR) +#endif + +#ifndef LIBSSH2_S_ISREG +#define LIBSSH2_S_ISREG(mode) (((mode) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG) +#endif + +struct RemoteFileInfo { + QString name; + qint64 size; + bool isDir; + uint permissions; + QDateTime lastModified; // 修改日期 + uint uid; // 用户ID + uint gid; // 组ID + QString owner; // 用户名 + QString group; // 组名 +}; + +class ScpClient : public QObject +{ + Q_OBJECT +public: + explicit ScpClient(QObject *parent = nullptr); + ~ScpClient(); + + bool connectToHost(const QString &host, + int port, + const QString &user, + const QString &password, + int timeoutMs = 10000); + + void disconnectFromHost(); + + bool download(const QString &remotePath, + const QString &localPath); + + bool upload(const QString &localPath, + const QString &remotePath,const QString& fileName,int type = -1, + int fileMode = 0644); + + void cancel(); + void uploadFinish(); + // ===== SFTP 相关 ===== + bool listRemoteDir(const QString &path, QVector &outList); + bool makeRemoteDir(const QString &path, int mode = 0755); + bool removeRemoteFile(const QString &path); + bool removeRemoteDir(const QString &path); + bool renameRemote(const QString &oldPath, const QString &newPath); + bool exec(const QString &cmd, QString &output); + void waitSocket(SOCKET sock); + bool goUp(); + + + QString m_currentPath; +signals: + void progress(qint64 current, qint64 total); + void error(const QString &msg); + void finished(); + +private: + int m_sock{-1}; + LIBSSH2_SESSION *m_session{nullptr}; + std::atomic_bool m_cancelled{false}; + int m_Type; + QString m_fileName; + + + QString uidToName(uint uid); + QString gidToName(uint gid); +};