Qt中ftp文件传输

目录

一、前期准备

二、Qt实现文档传输

1、准备ftp传输所使用到的工具(头文件)

2、使用ftp对象工具

总结:

拓展:


一、前期准备

首先ls查看目录,文档要是这样的绿标(这个文件夹要是读写权限,chmod 777+“加文件夹名字”)

如Downloads

然后输入下面2行命令

①、配置环境 

sudo apt-get install vsftpd

②、修改文档信息 

sudo gedit /etc/vsftpd.conf

 注意没有#号的地方,把前面的#去掉

 之后就可以用这个文档传输助手进行传输

        然而我们本篇则是教如何用QT实现ftp文档传输

二、Qt实现文档传输

1、准备ftp传输所使用到的工具(头文件)

ftp_sever.h

#ifndef FTP_SEVER_H
#define FTP_SEVER_H

#include <QObject>

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QUrl>

#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
class ftp_sever : public QObject
{
    Q_OBJECT
public:
    explicit ftp_sever(QObject *parent = nullptr);
    //设置登录信息
    void setFtpAuthrity(const QString &host,const QString& userName,const QString &password,quint16 port = 21);
    
    //上传和下载的功能
    void getFilefromSever(const QString &filename,const QString &path);
    void putFilefromSever(const QString &filename,const QString &path);
signals:
    void downloadProgressSignal(qint64,qint64);
    void uploadProgressSignal(qint64,qint64);

public slots:
    //下载进度
    void downloadProgressSlot(qint64,qint64);
    //下载出错
    void downloaderrorSlot(QNetworkReply::NetworkError);
    //下载是否完成
    void downloadFinishedSlot();
    
    //上传进度
    void uploadProgressSlot(qint64,qint64);
    //上传是否完成
    void upLoadFinisheSlot();
    //上传是否出错
    void uploadErrorSlot(QNetworkReply::NetworkError err);
private:
    QUrl mUrl;//网络路径
    QNetworkAccessManager mNetAccMag; //上传和下载的对象
    QNetworkReply *putNewReply;       //上传
    QNetworkReply *getNewReply;       //下载
    
    QFile* putfile;
    QFile* getfile;
    
    
};

#endif // FTP_SEVER_H

ftp_sever.cpp

#include "ftp_sever.h"

ftp_sever::ftp_sever(QObject *parent) : QObject(parent)
{
    mUrl.setScheme("ftp");  //设置协议
}

void ftp_sever::setFtpAuthrity(const QString &host, const QString &userName, const QString &password, quint16 port)
{
    mUrl.setScheme("ftp");
    mUrl.setHost(host);
    mUrl.setUserName(userName);
    mUrl.setPassword(password);
    mUrl.setPort(port);
}

void ftp_sever::getFilefromSever(const QString &filename, const QString &path)
{
    getfile = new QFile(filename,this);//保存在本地的路径
    mUrl.setPath(path);                //设置从服务器下载的路径

    if(getfile->open(QIODevice::WriteOnly))//打开文件
    {
        getNewReply = mNetAccMag.get(QNetworkRequest(mUrl));
        connect(getNewReply,
                SIGNAL(downloadProgress(qint64,qint64)),
                this,
                SLOT(downloadProgressSlot(qint64,qint64)));
        connect(getNewReply,
                SIGNAL(finished()),
                this,
                SLOT(downloadFinishedSlot())
                );
        connect(getNewReply,
                SIGNAL(error(QNetworkReply::NetworkError)),
                this,
                SLOT(downloaderrorSlot(QNetworkReply::NetworkError))
                );

    }else{
        delete getNewReply;
        getNewReply = NULL;
    }
}

void ftp_sever::putFilefromSever(const QString &filename, const QString &path)
{
    putfile = new QFile(filename,this);
    QString saveFileName = path+"/"+QFileInfo(filename).fileName();//文件在服务器上的绝对路径
    mUrl.setPath(saveFileName);

    if(putfile->open(QIODevice::ReadOnly)){
        putNewReply = mNetAccMag.put(QNetworkRequest(mUrl),putfile);

        connect(putNewReply,
                SIGNAL(uploadProgress(qint64,qint64)),
                this,
                SLOT(uploadProgressSlot(qint64,qint64))
                );
        connect(putNewReply,
                SIGNAL(finished()),
                this,
                SLOT(upLoadFinisheSlot())
                );
        connect(putNewReply,
                SIGNAL(error(QNetworkReply::NetworkError)),
                this,
                SLOT(uploadErrorSlot(QNetworkReply::NetworkError))
                );
    }else{
        delete putfile;
        putfile = NULL;
    }
}

//x表示下载到哪       y表示最多可以下载多少
void ftp_sever::downloadProgressSlot(qint64 x, qint64 y)
{
    emit downloadProgressSignal(x,y);

    QByteArray ba = getNewReply->readAll();
    if(ba.size())
    {
        getfile->write(ba);
    }
}

void ftp_sever::downloaderrorSlot(QNetworkReply::NetworkError err)
{
    getNewReply->deleteLater();//等会释放
    if(getfile){
        getfile->close();
        delete getfile;
        getfile = NULL;
    }

    //
}

void ftp_sever::downloadFinishedSlot()
{
    getNewReply->deleteLater();//等会释放,考虑到延迟问题
    if(getfile){
        getfile->close();
        delete getfile;
        getfile = NULL;
    }
}

void ftp_sever::uploadProgressSlot(qint64 x, qint64 y)
{
    emit uploadProgressSignal(x,y);
}

void ftp_sever::upLoadFinisheSlot()
{
    putNewReply->deleteLater();//等会释放,考虑到延迟问题
    if(putfile){
        putfile->close();
        delete putfile;
        putfile = NULL;
    }
}

void ftp_sever::uploadErrorSlot(QNetworkReply::NetworkError err)
{
    putNewReply->deleteLater();//等会释放,考虑到延迟问题
    if(putfile){
        putfile->close();
        delete putfile;
        putfile = NULL;
    }

    //
}

2、使用ftp对象工具

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "ftp_sever.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_down_clicked();

    void on_pushButton_up_clicked();
    void downloadProgressSlot(qint64,qint64);
    void uploadProgressSlot(qint64,qint64);
private:
    bool getFtpInfo();
private:
    Ui::Widget *ui;

    ftp_sever mFtpAccmgr;
    QString ftpHost;
    QString ftpUserName;
    QString ftpPsd;
    qint16 ftpPort;

};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(&mFtpAccmgr,
            SIGNAL(downloadProgressSignal(qint64,qint64)),
            this,
            SLOT(downloadProgressSlot(qint64,qint64))
            );
    connect(&mFtpAccmgr,
            SIGNAL(uploadProgressSignal(qint64,qint64)),
            this,
            SLOT(uploadProgressSlot(qint64,qint64))
            );
}

Widget::~Widget()
{
    delete ui;
}

bool Widget::getFtpInfo()
{
    //判断是否输入空
    ftpHost=ui->lineEdit_host->text();
    ftpPort=ui->lineEdit_port->text().toInt();
    ftpPsd=ui->lineEdit_psd->text();
    ftpUserName=ui->lineEdit_name->text();
    if(ftpHost.isEmpty()&&ftpPsd.isEmpty()&&ftpUserName.isEmpty())
        return false;
    return true;
}

void Widget::on_pushButton_down_clicked()
{
    if(!getFtpInfo())
    {
        QMessageBox::critical(this,"错误提示","输入的端口号、密码或者用户名为空");
        return;
    }
    mFtpAccmgr.setFtpAuthrity(ftpHost,ftpUserName,ftpPsd,ftpPort);

    QString downPath = ui->lineEdit_down->text();//从服务器下载的路径
    QString filename = QFileInfo(downPath).fileName();
    if(filename.isEmpty())
    {
        QMessageBox::critical(this,"错误提示","下载路径为空,");
        return;
    }
    QString savePath = QFileDialog::getSaveFileName(this,"保存为",filename);
    mFtpAccmgr.getFilefromSever(savePath,downPath);
}


void Widget::downloadProgressSlot(qint64 x, qint64 y)
{
    ui->progressBar_down->setMaximum(y);
    ui->progressBar_down->setValue(x);
}

void Widget::on_pushButton_up_clicked()
{
    ui->progressBar_up->setValue(0);
    if(!getFtpInfo())
    {
        QMessageBox::critical(this,"错误提示","输入的端口号、密码或者用户名为空");
        return;
    }
    mFtpAccmgr.setFtpAuthrity(ftpHost,ftpUserName,ftpPsd,ftpPort);
    QString fileName = QFileDialog::getOpenFileName(this,"上传的文件");
    if(fileName.isEmpty())
        return;
    QString savePath = ui->lineEdit_up->text();
    if(savePath.isEmpty())
        return;
    mFtpAccmgr.putFilefromSever(fileName,savePath);
}

void Widget::uploadProgressSlot(qint64 x,qint64 y)
{
    int fileSize=y/(1024*1024);
    if(fileSize==0&&y>0)    //当文件小于1m时候
        fileSize=1;

    int index=x/(1024*1024);
    if(index==0&&x>0)
        index=1;
    //qDebug()<<fileSize<<" "<<index;
    ui->progressBar_up->setMaximum(fileSize);
    ui->progressBar_up->setValue(index);
}

效果展示:

总结:

        首先由于不能跨线程,导致通过信号与槽的方式进行传输进度条来展示自己的下载进度

        然后根据io操作读取文件的路径,文件名

拓展:

ifconfig   查看
ipps -ef | grep ftp     查看ftp服务器是否启动
sudo netstat -anp |grep ftp       查看ftp的端口号

猜你喜欢

转载自blog.csdn.net/qq_54395977/article/details/122776710