一、需求:
1.简单的配置ftp参数界面
2.tcp 客户端端,接收服务器下发的参数信息
3.用户上传操作界面
在这里插入代码片
二、源码`#-------------------------------------------------
#-------------------------------------------------
#
# Project created by QtCreator 2021-06-24T15:49:34
#
#-------------------------------------------------QT += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = FtpFileShareTool
TEMPLATE = appSOURCES += main.cpp\FtpFileTool.cpp \DialogFTPSetting.cppHEADERS += FtpFileTool.h \DialogFTPSetting.hFORMS += FtpFileTool.ui \DialogFTPSetting.ui
// 主操作界面
#ifndef FTPFILETOOL_H
#define FTPFILETOOL_H#include <QWidget>
#include <QString>
#include <QUrl>
#include <QFile>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include "DialogFTPSetting.h"namespace Ui {
class FtpFileTool;
}class FtpFileTool : public QWidget
{Q_OBJECTpublic:explicit FtpFileTool(QWidget *parent = 0);~FtpFileTool();// 上传文件void put(const QString &fileName, const QString &path);private slots:void slot_put();void slot_applyNewConfig();void slot_uploadProgress(qint64 bytesSent, qint64 bytesTotal); // 更新上传进度void slot_error(QNetworkReply::NetworkError code);void slot_replyFinished(QNetworkReply*);private:Ui::FtpFileTool *ui;DialogFTPSetting m_dlgFtpSetting;QUrl m_pUrl; // 远程 ftp url 地址QFile m_file;QNetworkAccessManager *m_manager;QNetworkReply *m_pReply;QFile *m_pFile;
};#endif // FTPFILETOOL_H
#include "FtpFileTool.h"
#include "ui_FtpFileTool.h"
#include <QMessageBox>FtpFileTool::FtpFileTool(QWidget *parent) :QWidget(parent),ui(new Ui::FtpFileTool)
{ui->setupUi(this);connect(ui->pushButtonFTPSetting, &QPushButton::clicked, &m_dlgFtpSetting, &DialogFTPSetting::exec);m_pUrl.setScheme("ftp");m_manager = new QNetworkAccessManager(this);connect(&m_dlgFtpSetting, &DialogFTPSetting::sig_ftpConfigChanged, this, &FtpFileTool::slot_applyNewConfig);connect(ui->pushButtonPut, &QPushButton::clicked, this, &FtpFileTool::slot_put);connect(ui->lineEditRemotePath, &QLineEdit::textChanged, &m_dlgFtpSetting, &DialogFTPSetting::slot_setNewRemoteConfig);connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(slot_replyFinished(QNetworkReply*)));
}FtpFileTool::~FtpFileTool()
{delete ui;
}void FtpFileTool::slot_put()
{m_pFile = new QFile(ui->lineEditLocalPath->text());qDebug() <<"src file : "<< ui->lineEditLocalPath->text().toLatin1();if(false == m_pFile->open(QIODevice::ReadOnly)){QMessageBox messageBox(this);messageBox.setWindowTitle("erro");messageBox.setText("open file error");messageBox.exec();}else{QByteArray data = m_pFile->readAll();m_pUrl.setPath(ui->lineEditRemotePath->text());m_manager->setNetworkAccessible(QNetworkAccessManager::Accessible);m_pReply = m_manager->put(QNetworkRequest(m_pUrl), data);qDebug() << "文件内容:" << data;connect(m_pReply, &QNetworkReply::uploadProgress, this, &FtpFileTool::slot_uploadProgress);connect(m_pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slot_error(QNetworkReply::NetworkError)));if (m_pReply->error() != QNetworkReply::NoError){qDebug() << "Error: " << m_pReply->errorString();}m_pFile->close();}
}void FtpFileTool::slot_applyNewConfig()
{ m_pUrl.setHost(m_dlgFtpSetting.getRemoteIP());m_pUrl.setPort(21);m_pUrl.setUserName(m_dlgFtpSetting.getUserName());m_pUrl.setPassword(m_dlgFtpSetting.getPassword());if (m_dlgFtpSetting.getRemotePathSetting()!= "" ){m_pUrl.setPath(m_dlgFtpSetting.getRemotePathSetting().toLatin1());qDebug() <<"ftp 文件设置 " <<m_dlgFtpSetting.getRemotePathSetting().toLatin1();ui->lineEditRemotePath->setText(m_dlgFtpSetting.getRemotePathSetting());}qDebug() << m_pUrl.host() << m_pUrl.port() << m_pUrl.userName() << m_pUrl.password();//检测URL地址是否合法if (!m_pUrl.isValid()){QMessageBox::critical(NULL, tr("Error"), "URL地址不合法!" );}else if (m_pUrl.scheme() != "ftp"){QMessageBox::critical(NULL, tr("Error"), "URL地址必须以ftp开头!");}
}// 更新上传进度
void FtpFileTool::slot_uploadProgress(qint64 bytesSent, qint64 bytesTotal)
{ui->progressBarUpload->setMaximum(bytesTotal);ui->progressBarUpload->setValue(bytesSent);
}void FtpFileTool::slot_error(QNetworkReply::NetworkError code)
{QMessageBox messageBox(this);messageBox.setWindowTitle("erro");messageBox.setText("upload error, "+QString::number(code).toLatin1());messageBox.exec();
}// 删除指针,更新和关闭文件
void FtpFileTool::slot_replyFinished(QNetworkReply*)
{if (m_pReply->error() == QNetworkReply::NoError){m_pReply->deleteLater();m_pFile->flush();m_pFile->close();}else{QMessageBox::critical(NULL, tr("Error"), "错误!!!");}
}
// 参数配置界面和参数接收
#ifndef DIALOGFTPSETTING_H
#define DIALOGFTPSETTING_H#include <QDialog>
#include <QTcpSocket>namespace Ui {
class DialogFTPSetting;
}class DialogFTPSetting : public QDialog
{Q_OBJECTpublic:explicit DialogFTPSetting(QWidget *parent = 0);~DialogFTPSetting();QString getRemotePathSetting();QString getRemoteIP();QString getRemotePort();QString getUserName();QString getPassword();public slots:void slot_setNewRemoteConfig(const QString strPath);signals:void sig_ftpConfigChanged(); // 参数配置改变的时候发出信号private slots:void slot_getRemoteConfig(); // 接受远程参数配置数据void slot_connectOrDisconnect(); // 确认参数,并建立链接, 接受远程参数设置void slot_updateAsDisconnected(); // 被动断开界面刷新void slot_sureConfig();private:Ui::DialogFTPSetting *ui;QTcpSocket m_clientSocket;
};#endif // DIALOGFTPSETTING_H```cpp
#include "DialogFTPSetting.h"
#include "ui_DialogFTPSetting.h"
#include <QHostAddress>
DialogFTPSetting::DialogFTPSetting(QWidget *parent) :QDialog(parent),ui(new Ui::DialogFTPSetting)
{ui->setupUi(this);connect(ui->pushButtonConnect, &QPushButton::clicked, this, &DialogFTPSetting::slot_connectOrDisconnect);connect(&m_clientSocket, &QTcpSocket::disconnected, this, &DialogFTPSetting::slot_updateAsDisconnected);connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &DialogFTPSetting::slot_sureConfig);
}DialogFTPSetting::~DialogFTPSetting()
{delete ui;
}QString DialogFTPSetting::getRemotePathSetting()
{return ui->lineEdit_RecvMsg->text().toLatin1();
}QString DialogFTPSetting::getRemoteIP()
{return ui->lineEditIP->text();
}QString DialogFTPSetting::getRemotePort()
{return ui->lineEditPort->text();
}QString DialogFTPSetting::getUserName()
{return ui->lineEditUserName->text();
}QString DialogFTPSetting::getPassword()
{return ui->lineEditPassword->text();
}void DialogFTPSetting::slot_getRemoteConfig()
{QByteArray recvByts = m_clientSocket.readAll();QString strRecv = QString(recvByts);ui->lineEdit_RecvMsg->setText(strRecv.toLatin1());// m_remoteConfig = strRecv.toLatin1();
}void DialogFTPSetting::slot_setNewRemoteConfig(const QString strPath)
{ui->lineEdit_RecvMsg->setText(strPath);
}void DialogFTPSetting::slot_connectOrDisconnect()
{if(ui->pushButtonConnect->text() == tr("断开")){m_clientSocket.disconnectFromHost();ui->lineEditIP->setEnabled(true);ui->lineEditPassword->setEnabled(true);ui->lineEditPort->setEnabled(true);ui->lineEditUserName->setEnabled(true);ui->pushButtonConnect->setText("连接");}else{quint16 port = ui->lineEditPort->text().toUInt();QHostAddress ip(ui->lineEditIP->text());m_clientSocket.connectToHost(ip, port);// 监听接受配置connect(&m_clientSocket, &QIODevice::readyRead, this, &DialogFTPSetting::slot_getRemoteConfig);if(m_clientSocket.isOpen()){ui->lineEditIP->setEnabled(false);ui->lineEditPassword->setEnabled(false);ui->lineEditPort->setEnabled(false);ui->lineEditUserName->setEnabled(false);ui->pushButtonConnect->setText("断开");}}
}void DialogFTPSetting::slot_updateAsDisconnected()
{ui->lineEditIP->setEnabled(true);ui->lineEditPassword->setEnabled(true);ui->lineEditPort->setEnabled(true);ui->lineEditUserName->setEnabled(true);ui->pushButtonConnect->setText("连接");
}void DialogFTPSetting::slot_sureConfig()
{emit sig_ftpConfigChanged();
}
三、坑
1.远程路径, 使用QUrl 的setPath() 函数来设定远程文件时候,文件路径不包含ftp://ip// , 这个部分应该是在 设置ftp ip 时候已经默认了,用户在setpath 只要告诉 下图 path 这部分,否则会有 网络错误码201