一、需求:
1.简单的配置ftp参数界面
2.tcp 客户端端,接收服务器下发的参数信息
3.用户上传操作界面在这里插入代码片
二、源码`#-------------------------------------------------
#-------------------------------------------------
#
# Project created by QtCreator 2021-06-24T15:49:34
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = FtpFileShareTool
TEMPLATE = app
SOURCES += main.cpp\
FtpFileTool.cpp \
DialogFTPSetting.cpp
HEADERS += FtpFileTool.h \
DialogFTPSetting.h
FORMS += 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_OBJECT
public:
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_OBJECT
public:
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