代码先锋网 代码片段及技术文章聚合

QT使用FTP同步/异步上传和下载文件,ubuntu下ftp服务器搭建

技术标签: QT  qt  ubuntu  ftp


本章介绍ubuntu下FTP服务器搭建,使用QT进行FTP同步/异步上传下载,同步模式增加传输超时机制,QT上传下载的代码在windows下通用。

ubuntu下ftp服务器搭建

安装ftp服务:sudo apt-get install vsftpd
修改vsftp的配置文件:sudo gedit /etc/vsftpd.conf

将配置文件中”anonymous_enable=YES “改为 “anonymous_enable=NO”(是否允许匿名ftp,若不允许选NO),并且取消如下配置前的注释符号:
local_enable=YES(是否允许本地用户登录)
write_enable=YES(是否允许本地用户写的权限)
chroot_local_user=YES(是否将所有用户限制在主目录)
chroot_list_enable=YES(是否启动限制用户的名单)
chroot_list_file=/etc/vsftpd.chroot_list(可在文件中设置多个账号)
Vsftpd的默认端口为21, 若21已被占用可更换端口号,如在该配置文件中添加: listen_port=2121,即可监听2121端口

设置支持登录的用户列表:

#直接把用户名添加进去
sudo gedit /etc/vsftpd.chroot_list

重启FTP服务

sudo service vsftpd restart

FTP测试

ftp 127.0.0.1#登录ftp服务器,随后输入账号密码,进入ftp命令行
get filename#下载文件
put filename#上传文件
bye#退出登录

QT实现FTP同步上传,增加超时机制

这里只介绍同步上传,同步下载类似

/**
 * @brief ftp上传文件
 * @param filePath 上传文件的全路径
 * @param strUrl ftp服务器地址
 * @param port ftp端口号,默认21
 * @param username ftp帐号
 * @param passwd ftp密码
 * @param lastError 错误信息
 * @return 错误信息,为空则上传成功
 */
QString Instance_Relay::FtpUploadFile(QString filePath, QString strUrl, QString port, QString username, QString passwd)
{
    QString rtnMsg = "";

    QFile *file;
    file = new QFile(filePath);
    file->open(QIODevice::ReadOnly);
    QByteArray byte_file = file->readAll();

    CLOG_WRITEFILE(CLOG_FTP,QString("开始FTP上传,文件名=%1,ftp路径=%2,ftp端口=%3,ftp用户名=%4,ftp密码=%5")
                   .arg(filePath)
                   .arg(strUrl)
                   .arg(port)
                   .arg(username)
                   .arg(passwd));
    CLOG_WRITEFILE(CLOG_FTP,"文件内容:");
    CLOG_WRITEFILE(CLOG_FTP,byte_file);

    QString fileName;
    fileName = Instance::getInstance()->getFileName(filePath);
    QString m_ftpPath;
    m_ftpPath = strUrl + "/" + fileName;//上传到服务器的全路径,ftp://127.0.0.1/test.jpg

    QUrl url(m_ftpPath);
    url.setPort(port.toInt());
    url.setUserName(username);
    url.setPassword(passwd);

    QNetworkReply* oNetReply = nullptr;
    QNetworkAccessManager oNetAccessManager;
    QNetworkRequest request(url);
    oNetReply = oNetAccessManager.put(request, byte_file);

    // 添加超时处理
    QEventLoop eventloop;
    connect(oNetReply, SIGNAL(finished()), &eventloop, SLOT(quit()));
    //3000ms未能完成上传,则超时
    QTimer::singleShot(3000, &eventloop, &QEventLoop::quit);
    eventloop.exec();

    QByteArray array;
    if(oNetReply->isFinished())
    {
        if(oNetReply->error() == QNetworkReply::NoError)//正常结束,可读取响应数据
        {
            CLOG_WRITEFILE(CLOG_FTP,"ftp上传文件成功");
        }
        else//异常结束,比如不存在的服务器,错误信息:Connection refused
        {
            CLOG_WRITEFILE(CLOG_FTP,"ftp上传文件失败,异常结束");
        }
    }
    else//超时,错误信息:Operation canceled
    {
        disconnect(oNetReply, &QNetworkReply::finished, &eventloop, &QEventLoop::quit);
        oNetReply->abort();
        CLOG_WRITEFILE(CLOG_FTP,"ftp上传文件超时");
    }

    QNetworkReply::NetworkError e = oNetReply->error();//获取错误信息
    if (e)
    {
        rtnMsg = oNetReply->errorString();
    }
    oNetReply->deleteLater();
    file->close();
    return rtnMsg;
}

调用示例:

    QString rtnMsg = Instance_Relay::getInstance()->FtpUploadFile("/home/chw/Company/123456.txt","ftp://127.0.0.1","21","chw","chw123");
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<<rtnMsg;

QT实现FTP异步上传和下载

ftpclient.h

#ifndef FTPCLIENT_H
#define FTPCLIENT_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QMessageBox>
#include <QFileDialog>
#include <QMetaEnum>
#include <QUrl>
#include <QFile>
#include <QDir>
class FtpClient : public QObject
{
    Q_OBJECT
public:
    explicit FtpClient(QObject *parent = nullptr);
    bool initFTP(QString ftpUrl, QString username, QString passwd);//初始化ftp参数
    QString getFileName(QString m_filePath);//获得传入路径的文件名
    void upload(QString filePath);//上传文件
    void download(QString fileUrl, QString localFilePath);//下载文件

    QString FtpUploadFile(QString filePath, QString strUrl, QString port, QString username, QString passwd);///ftp上传文件
public slots:
    void replyFinished(QNetworkReply*);//上传或下载完成
    void loadProgress(qint64 bytesSent, qint64 bytesTotal);//上传进度
    void replyError(QNetworkReply::NetworkError error);//网络传输出错
    void readContent();//下载时向本地文件中写入数据
private:
    bool FTP_initFlag;//ftp参数是否完成初始化
    QNetworkAccessManager *accessManager;
    QString ftpPath;
    QString user;
    QString password;
    QFile *file;
    QNetworkReply *reply;
};

ftpclient.cpp

#include "ftpclient.h"

#include <QEventLoop>
#include <QTimer>
#include "common/clog.h"

FtpClient::FtpClient(QObject *parent) : QObject(parent)
{
    FTP_initFlag = false;

    accessManager = new QNetworkAccessManager(this);
    accessManager->setNetworkAccessible(QNetworkAccessManager::Accessible);
}

/**
 * @brief 初始化记录URL地址,用户名,密码,并检测URL地址的合法性
 * @param ftpUrl ftp服务器地址
 * @param username 用户名
 * @param passwd 密码
 * @return  是否初始化成功
 */
bool FtpClient::initFTP(QString ftpUrl, QString username, QString passwd)
{
    ftpPath = ftpUrl;
    user = username;
    password = passwd;
    //检测URL地址是否合法
    QUrl url = QUrl(ftpPath);
    if (!url.isValid())
    {
        CLOG_WRITEFILE(CLOG_FTP,QString("URL地址不合法:%1").arg(ftpUrl).toUtf8().data());
        return false;
    }
    else if (url.scheme() != "ftp")
    {
        CLOG_WRITEFILE(CLOG_FTP,QString("URL地址必须以ftp开头:%1").arg(ftpUrl).toUtf8().data());
        return false;
    }

    CLOG_WRITEFILE(CLOG_FTP,QString("FTP参数初始化完成,url=%1,username=%2,passwd=%3").arg(ftpUrl).arg(username).arg(passwd).toUtf8().data());
    FTP_initFlag = true;
    return true;
}

/***********************************************************************************************
*函数名 : replyFinished
*函数功能描述 : 删除指针,更新和关闭文件
***********************************************************************************************/
void FtpClient::replyFinished(QNetworkReply*)
{
    if (reply->error() == QNetworkReply::NoError)
    {
        reply->deleteLater();
        file->flush();
        file->close();
        CLOG_WRITEFILE(CLOG_FTP,"传输完成");
    }
    else
    {
        CLOG_WRITEFILE(CLOG_FTP,QString("传输结束,出错:%1").arg(reply->errorString()));
    }
}

/**
 * @brief 上传进度
 * @param bytesSent 当前值
 * @param bytesTotal 最大值
 */\
void FtpClient::loadProgress(qint64 bytesSent, qint64 bytesTotal)
{
    if(bytesSent >= bytesTotal)
    {
        //上传完成
        CLOG_WRITEFILE(CLOG_FTP,QString("传输完成,当前值:%1,最大值:%2").arg(QString::number(bytesSent)).arg(QString::number(bytesTotal)));
    }
}

/**
 * @brief 获得传入路径的文件名
 * @param m_filePath 文件全路径
 * @return  文件名
 */
QString FtpClient::getFileName(QString m_filePath)
{
    QString temp;
    QString fileName;
    int count = -1;
    fileName = m_filePath;
    for(int i = 0; temp != "/"; i++)
    {
        temp = fileName.right(1);
        fileName.chop(1);
        count++;
    }
    fileName = m_filePath.right(count);

    return fileName;
}

/**
 * @brief FTP传输出错
 * @param error 错误信息
 */
void FtpClient::replyError(QNetworkReply::NetworkError error)
{
    auto metaEnum = QMetaEnum::fromType<QNetworkReply::NetworkError>();
    //枚举值转换为字符串
    auto errStr = metaEnum.valueToKey(error);
    QMessageBox::critical(nullptr, tr("Error"), QString(errStr));
    file->deleteLater();
    file = Q_NULLPTR;
    reply->deleteLater();
}

//下载时向本地文件中写入数据
void FtpClient::readContent()
{
    file->write(reply->readAll());
}

/**
 * @brief 上传文件
 * @param filePath 上传文件的全路径
 */
void FtpClient::upload(QString filePath)
{
    if(FTP_initFlag == false)
    {
        CLOG_WRITEFILE(CLOG_FTP,"上传失败,FTP未初始化");
        return;
    }

    file = new QFile(filePath);
    file->open(QIODevice::ReadOnly);
    QByteArray byte_file = file->readAll();

    QString fileName;
    fileName = getFileName(filePath);
    QString m_ftpPath;
    m_ftpPath = ftpPath + "/" + fileName;//上传到服务器的全路径,ftp://127.0.0.1/test.jpg

    //把文件上传到服务器
    QUrl url(m_ftpPath);
    url.setPort(21);
    url.setUserName(user);
    url.setPassword(password);

    QNetworkRequest request(url);
    reply = accessManager->put(request, byte_file);

connect(accessManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*)));
    connect(reply, SIGNAL(uploadProgress(qint64 ,qint64)), this, SLOT(loadProgress(qint64 ,qint64)));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),SLOT(replyError(QNetworkReply::NetworkError)));
}

/**
 * @brief 下载文件
 * @param fileUrl ftp服务器上的文件URL,包含文件名
 * @param localFilePath 保存到本地的全路径,包含文件名
 */
void FtpClient::download(QString fileUrl,QString localFilePath)
{
    if(FTP_initFlag == false)
    {
        CLOG_WRITEFILE(CLOG_FTP,"下载失败,FTP未初始化");
        return;
    }

    file = new QFile(localFilePath);
    file->open(QIODevice::WriteOnly);

    //从服务器上下载文件到选中文件夹
    QUrl url(fileUrl);
    url.setPort(21);
    url.setUserName("jinxiaodan");
    url.setPassword("abcd1234");

    QNetworkRequest request(url);
    reply = accessManager->get(request);

    connect((QObject *)reply, SIGNAL(readyRead()), this, SLOT(readContent()));
    connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    connect(reply, SIGNAL(downloadProgress(qint64 ,qint64)), this, SLOT(loadProgress(qint64 ,qint64)));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),SLOT(replyError(QNetworkReply::NetworkError)));
}

调用示例

 gp_FtpClient->initFTP("ftp://127.0.0.1","chw","chw123");
 gp_FtpClient->upload("/home/chw/Company/123456.txt");
版权声明:本文为weixin_40355471原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40355471/article/details/123114209

智能推荐

python 利用ftp上传文件至服务器、从服务器下载文件

ftplib模块是Python中默认安装的,通过它定义的FTP类中的各个函数,可以完成对FTP服务器的操作,既能实现简单的ftp客户端,也可以连接或者操作FTP服务端,完成文件上传或下载。 1.函数介绍 ftplib模块中各个函数功能如下: 2 .python实现 利用FTP上传文件、下载文件到服务器 案例二: 利用ftp上传文件至服务器 该功能为通过前端上传文件,后端通过ftp将文件传至另一台配...

Ubuntu下搭建ftp服务器

前言:   最近项目需要搭建第三方文件服务器,本来使用的是apache服务器将需要的子项目的目录发布出来,然后通过软连接将所有子项目关联起来,但是如果不同时将所有子项目跑起来的话,未开启的项目目录就会丢失,着实蛋疼,所以才有搭建ftp服务器的想法,下面开始正文。 一、安装 如果是ubuntu环境下的话,安装是很简单的,只需输入如下命令: 安装 sudo apt-get install vsftpd...

Ubuntu下搭建ftp服务器

ftp服务器是个好东西啊= = 首先需要安装一个软件vsftpd sudo aptitude install vsftpd 如果想要更改匿名登录指向的目录可以使用 sudo dpkg-reconfigure vsftpd 修改配置文件/etc/vsftpd.conf anonymous_enable=YES # 匿名访问允许 anon_upload_enable=YES # 匿名上传允许 其他的类...

Ubuntu下搭建FTP服务器

在Linux中ftp服务器的全名叫 vsftpd,我们需要利用相关命令来开启安装ftp服务器,然后再在vsftpd.conf中进行相关配置,下面我来介绍在Ubuntu中vsftpd安装与配置增加用户的方法。 (1)、首先用命令检查是否安装了vsftpd 如果未安装用一下命令安装 安装完成后,再次输入vsftpd -version命令查看是否安装成功 (2)、新建一个文件夹用于FTP的工作目录 ft...

Ubuntu下ftp服务器搭建

Ubuntu下ftp服务器搭建 1.安装vsftpd 安装完成后启动vsftpd服务: 2.新建目录/home/uftp(用户名)作为用户主目录 3.新建用户uftp,制定用户主目录和所用shell,并设置密码 设置密码 然后将目录/home/uftp的所属者和所属组都改为uftp: 4.新建文件/etc/vsftpd.user_list,用于存放允许访问ftp的用户: 在其中添加用户uftp,并...

猜你喜欢

ubuntu下ftp服务器搭建

ubuntu下ftp服务器搭建 1、安装vsftpd 查看版本 2、新建ftp/upload目录并修改权限 3、修改vsftpd.conf文件 加入如下内容: 4、重启ftp服务 参考链接:https://www.cnblogs.com/oukele/p/11452651.html...

ubuntu下搭建ftp服务器

1.安装vsftpd,安装命令: 查看是否安装成功: 2、新建一个文件夹用于FTP的工作目录(cpucard是我自建的文件夹,把ftp文件夹放在这个里面) mkdir /home/cpucard/ftp 3、配置vsftpd.conf文件 打开文件进行编辑: 然后开始配置一下信息: 注:1. 以下信息均为常用设置,如有特殊需要,就随意啦。      ...

新建ftp站点,使用代码从ftp服务器下载文件(mfc)

使用个人电脑新建ftp站点:   打开控制面板》程序》启用或关闭windows功能》勾选Internet信息服务所有单选框》确定》找到IIS管理器(直接搜索程序位置吧)并打开》在左侧菜单右击“网站”》新建ftp站点》选择物理路径》输入IP(选择下拉框里的IP,这是本机ipv4地址)》无需ssl(你喜欢勾选也可以的,随你吧)》基本(选择匿名的话访问时就不需要密码),...

向FTP服务器上传、下载和删除文件

1. 获取FTP连接2. 上传文件 boolean success = false; final FTPClient ftpClient = getFTPClient(hostname, port, username, password); // 获取绝对路径 final String absPath = path; log.info("FTP 上传文件中。。。fileName=&quo...