搭建文件服务器并使用Qt实现文件上传和下载(带账号和密码)

news2024/11/26 9:46:28

文章目录

  • 0 背景
  • 1 搭建文件服务器
  • 2 代码实现文件上传和下载
    • 2.1 在pro文件中添加网络支持
    • 2.2 创建网络管理类
    • 2.3 文件上传
    • 2.4 文件下载
  • 3 扩展(其他方法实现文件上传和下载)
    • 3.1 python
    • 3.2 npm
    • 3.3 ftp服务器
  • 4 完整的代码

0 背景

因为需要使程序具备在远程软件在服务器的上传和下载文件的功能,所以研究了一下怎么实现。

在这里插入图片描述

在这里插入图片描述

1 搭建文件服务器

常用的文件服务器有apache、npm、ftp,这里选择的apache2,因为搭建和使用都比较方便。

1,安装

sudo apt update
sudo apt install apache2

2,创建身份验证用户::

# 新增用户
htpasswd -c /etc/apache2/webdav.password 【webdav用户名】

# 更改密码
htpasswd -b /etc/apache2/webdav.password 【这里换成你要登录webdav的名字】 

# 删除用户
htpasswd -D htpasswd.user Jack

3,编写配置文件

vim /etc/apache2/sites-available/000-default.conf

修改为如下内容:

<VirtualHost *:9022>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        
<Directory  "/var/www/html">
          Dav on
          Options Indexes FollowSymLinks MultiViews
          AllowOverride All
          Require all granted
          allow from all
</Directory>

DavLockDB "/home/apache2/data/DavLock"
# 配置一个虚拟目录
Alias /webdav /home/apache2/data

<Directory /home/apache2/data>
#开启Dav支持
        Dav On
# 禁止浏览器显示目录,将-Indexes前的减号去掉为允许显示(当index.html不存在时)
        Options Indexes
# 认证方式,虽然这种方式不安全但可以快速架设成功我们需要的服务        
        AuthType Basic
 # 这里的名字随意写        
        AuthName "WebDAV"
 # 非常关键的用户管理文件       
        AuthUserFile /etc/apache2/webdav.password
        AuthBasicProvider file
 # 允许userfile.pass里的所有用户访问       
        Require valid-user
        AllowOverride All
</Directory>

</VirtualHost>

授予文件访问权限:

sudo chmod 775 /var/www

4,启动并使其自动运行:

sudo systemctl start apache2
sudo systemctl status apache2
sudo systemctl enable apache2

5,其他指令

# 重启 Apache(完全停止并重新启动 Apache 服务。这适用于那些进行了重大更改并需要完全重启服务的情况):
sudo systemctl restart apache2

# systemctl reload 只是重新加载 Apache 的配置文件,而不会中断服务的运行:
sudo systemctl reload apache2

2 代码实现文件上传和下载

2.1 在pro文件中添加网络支持

QT += network

2.2 创建网络管理类

# .h文件中添加:

private:
    //发送网络请求和接受应答
    QNetworkAccessManager* m_networkAccessManager;

# .cpp文件中添加:
  m_networkAccessManager = new QNetworkAccessManager();

2.3 文件上传

1,功能函数;

//上传文件
void MainInterface::uploadFileFromHttpServerApacheWebdav(QString sourceFilePath, QString purposeFilePath)
{

   // QFile file(sourceFilePath);
    m_readFile.setFileName(sourceFilePath);

    if (m_readFile.open(QIODevice::ReadOnly)){


        QFileInfo fileInfo(sourceFilePath);
        QString fileName = fileInfo.fileName();

        //如果目的文件名,使用原文件名
        if(purposeFilePath == ""){
            purposeFilePath = fileName;
        }

        QString urlText = QString("http://192.168.0.211:9022/webdav/") + purposeFilePath;
        qDebug()<<urlText;
        QUrl url(urlText);

        // 设置用户名和密码凭据
        QString username = "uploaduser2";
        QString password = "test";
        url.setUserName(username);
        url.setPassword(password);
        m_httpRequest.setUrl(url);

        m_networkAccessManager->put(m_httpRequest, &m_readFile);

    }else{
        qDebug()<<"打开文件失败";
    }

}

2,方法调用;

    //文件上传
    QString sourceFilePath = QString("E:/s1.xlsx");
    QString purposeFilePath = "";
    uploadFileFromHttpServerApacheWebdav(sourceFilePath, purposeFilePath);

2.4 文件下载

这里下载使用的是post方法,而没有使用get。

1,功能函数;

//从服务器上下载文件
void MainInterface::downloadFileFromHttpServerApacheWebdav(QString sourceFilePath, QString purposeFilePath){
    QString urlText = QString("http://192.168.0.211:9022/webdav/") + sourceFilePath;
    QUrl url(urlText);
    // 设置用户名和密码凭据
    QString username = "uploaduser2";
    QString password = "test";
    url.setUserName(username);
    url.setPassword(password);
    m_httpRequest.setUrl(url);

    QString saveFilePath = QCoreApplication::applicationDirPath() + QString("/") ;//末尾无斜杠
    m_purposeSaveFilePath = saveFilePath  + purposeFilePath;
    m_isReceiveFile = true;
    m_networkAccessManager->get(m_httpRequest);

}


    //处理所有post请求
    connect(m_networkAccessManager, &QNetworkAccessManager::finished,
            this, [&](QNetworkReply *reply){
        if (reply->error()) {
            qDebug() << "Download error:" << reply->errorString();
        } else {
            //接收并下载文件
            if(m_isReceiveFile == true){
                m_isReceiveFile = false;

                // 处理获取到的文件内容
                QByteArray fileData = reply->readAll();
                qDebug() << "写入下载的数据:"<<m_purposeSaveFilePath;

                QFile file(m_purposeSaveFilePath);

                //QFile file(purposeFilePath);
                if (file.open(QIODevice::WriteOnly)) {
                    file.write(fileData);
                    file.close();
                }

            }else{
                QVariant data = reply->readAll();
                qDebug()<<data.toString();

            }
        }
        reply->deleteLater();
    });

2,方法调用;

    QString sourceFilePath = "s5.xlsx";
    QString purposeFilePath = "data/s5.xlsx";
    downloadFileFromHttpServerApacheWebdav(sourceFilePath, purposeFilePath);

3 扩展(其他方法实现文件上传和下载)

3.1 python

下载和安装python3,然后使用如下指令开启服务器

python -m http.server -b 127.0.0.1 

3.2 npm

1,安装
执行代码:

 npm install http-server -g

-g 参数代表全局安装一定不要省略,全局安装后,全局都可以使用

2,在需要共享的文件夹下,运行

http-server

3.3 ftp服务器

1,安装(https://www.myfreax.com/how-to-setup-ftp-server-with-vsftpd-on-debian-11/)

sudo apt update
sudo apt install vsftpd
sudo systemctl status vsftpd

2,新建ftp登录账户

# 创建一个帐户
sudo adduser ftpuser

# 为了让用户能够访问FTP服务器,你需要将其添加到FTP用户组中。输入以下命令:

sudo usermod -a -G ftp ftpuser

3,修改配置文件

修改/etc/shells

sudo vim /etc/shells

#写入以下这行,否则ftpuser无法登录
/usr/sbin/nologin

修改内容:

# 启用上传
write_enable=YES

#限制ftp用户只能待在自己的家目录,不能跳到其他目录
chroot_local_user=YES       
allow_writeable_chroot=YES   #不加入这条会导致ftp用户对家目录没有写入权限


chroot_local_user=YES        #限制ftp用户只能待在自己的家目录,不能跳到其他目录
userlist_enable=YES          #使用userlist限制可以登录ftp的账户
userlist_deny=NO             #这里是NO则userlist是白名单,YES就是黑名单

4,重启vsftpd服务

sudo systemctl restart vsftpd
systemctl start vsftpd.service
sudo systemctl status vsftpd

4 完整的代码

MainInterface.h

#ifndef MAIN_INTERFACE_H
#define MAIN_INTERFACE_H

#include <QMainWindow>

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainInterface;
}
QT_END_NAMESPACE

class MainInterface : public QMainWindow
{
    Q_OBJECT

public:
    MainInterface(QWidget *parent = nullptr);
    ~MainInterface();

private:
    Ui::MainInterface *ui;

private:
    //发送网络请求和接受应答
    QNetworkAccessManager* m_networkAccessManager;

    //是否是接收文件
    bool m_isReceiveFile = false;
    //目的存储路径
    QString m_purposeSaveFilePath;
    //请求
    QNetworkRequest m_httpRequest;
    //文件下载
    QFile m_readFile;

    /**
     * @brief downloadFileFromHttpServerApacheWebdav:从apache2服务器上下载文件(get)
     * @param sourceFilePath:源文件路径(最前面不带/,)
     * @param purposeFilePath:目的文件路径(最前面不带/,最前面包含了运行文件的路径)
     */
    void downloadFileFromHttpServerApacheWebdav(QString sourceFilePath, QString purposeFilePath);

    /**
     * @brief 上传文件到服务器上(put)
     * @param sourceFilePath
     * @param purposeFilePath
     */
    void uploadFileFromHttpServerApacheWebdav(QString sourceFilePath, QString purposeFilePath);
};
#endif // MAIN_INTERFACE_H

MainInterface.cpp

#include "main_interface.h"
#include "ui_main_interface.h"

#include <QDebug>

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QObject>
#include <QFile>
#include <QFileInfo>

MainInterface::MainInterface(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainInterface)
{
    ui->setupUi(this);

    // qDebug() << QSslSocket::supportsSsl()//是否支持,不支持就说明没有openSSL
    //          << QSslSocket::sslLibraryBuildVersionString()//运行时需要的版本
    //          << QSslSocket::sslLibraryVersionString();//可用的版本


    m_networkAccessManager = new QNetworkAccessManager();


    //处理所有post请求
    connect(m_networkAccessManager, &QNetworkAccessManager::finished,
            this, [&](QNetworkReply *reply){
        if (reply->error()) {
            qDebug() << "Download error:" << reply->errorString();
        } else {
            //接收并下载文件
            if(m_isReceiveFile == true){
                m_isReceiveFile = false;

                // 处理获取到的文件内容
                QByteArray fileData = reply->readAll();
                qDebug() << "写入下载的数据:"<<m_purposeSaveFilePath;

                QFile file(m_purposeSaveFilePath);

                //QFile file(purposeFilePath);
                if (file.open(QIODevice::WriteOnly)) {
                    file.write(fileData);
                    file.close();
                }

            }else{
                QVariant data = reply->readAll();
                qDebug()<<data.toString();

            }
        }
        reply->deleteLater();
    });

    //文件下载
    // QString sourceFilePath = "s5_ExamineExamOne_1721294100.xlsx";
    // QString purposeFilePath = "data/s5_ExamineExamOne_1721294100.xlsx";
    // downloadFileFromHttpServerApacheWebdav(sourceFilePath, purposeFilePath);

    //文件上传
    QString sourceFilePath = QString("E:/s1.xlsx");
    QString purposeFilePath = "";
    uploadFileFromHttpServerApacheWebdav(sourceFilePath, purposeFilePath);


}

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

//从服务器上下载文件
void MainInterface::downloadFileFromHttpServerApacheWebdav(QString sourceFilePath, QString purposeFilePath){
    QString urlText = QString("http://192.168.0.211:9022/webdav/") + sourceFilePath;
    QUrl url(urlText);
    // 设置用户名和密码凭据
    QString username = "uploaduser2";
    QString password = "test";
    url.setUserName(username);
    url.setPassword(password);
    m_httpRequest.setUrl(url);

    QString saveFilePath = QCoreApplication::applicationDirPath() + QString("/") ;//末尾无斜杠
    m_purposeSaveFilePath = saveFilePath  + purposeFilePath;
    m_isReceiveFile = true;
    m_networkAccessManager->get(m_httpRequest);

}

//上传文件
void MainInterface::uploadFileFromHttpServerApacheWebdav(QString sourceFilePath, QString purposeFilePath)
{

   // QFile file(sourceFilePath);
    m_readFile.setFileName(sourceFilePath);

    if (m_readFile.open(QIODevice::ReadOnly)){


        QFileInfo fileInfo(sourceFilePath);
        QString fileName = fileInfo.fileName();

        //如果目的文件名,使用原文件名
        if(purposeFilePath == ""){
            purposeFilePath = fileName;
        }

        QString urlText = QString("http://192.168.0.211:9022/webdav/") + purposeFilePath;
        qDebug()<<urlText;
        QUrl url(urlText);

        // 设置用户名和密码凭据
        QString username = "uploaduser2";
        QString password = "test";
        url.setUserName(username);
        url.setPassword(password);
        m_httpRequest.setUrl(url);

        m_networkAccessManager->put(m_httpRequest, &m_readFile);

    }else{
        qDebug()<<"打开文件失败";
    }

}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【初阶数据结构和算法】leetcode刷题之设计循环队列

文章目录 一、实现循环队列1.大致思路分析2.循环队列的结构定义和初始化结构定义初始化 3.循环队列的判空和判满判空和判满难点分析判空判满 4.循环队列的入队列和出队列入队列出队列 5.循环队列取队头和队尾元素取队头元素取队尾元素 6.循环队列的销毁7.最后题解源码 一、实现…

llama-factory 系列教程 (七),Qwen2.5-7B-Instruct 模型微调与vllm部署详细流程实战

文章目录 介绍llama-factory 安装装包下载模型 微调模型数据集训练模型 微调后的模型推理 介绍 时隔已久的 llama-factory 系列教程更新了。本篇文章是第七篇&#xff0c;之前的六篇&#xff0c;大家酌情选看即可。 因为llama-factory进行了更新&#xff0c;我前面几篇文章的实…

矩阵的重复

重复时自身也算一次重复 r e p m a t ( r e p e a t repmat(repeat repmat(repeat m a t l a b ) matlab) matlab)重复矩阵函数 ( ( ( 对矩阵整体 ) ) ) r e p m a t ( a , m , n ) repmat(a,m,n) repmat(a,m,n)将矩阵纵向重复 m m m次&#xff0c;横向重复 n n n次 r e …

【三维重建】windows10环境配置tiny-cuda-nn详细教程

1. 前言 本人在复现water-splatting时&#xff0c;需要配置tiny-cuda-nn&#xff0c;与此同时&#xff0c;出现了很多问题&#xff0c;在此进行简单概述。 2.安装Pytorch 环境版本要求保持一致&#xff1a;CUDA(物理机)&#xff0c;Pytorch&#xff0c;CUDA Toolkit 注意这里…

Js-函数-03

函数定义 在java中我们为了提高代码的复用性&#xff0c;可以使用方法。同样&#xff0c;在JavaScript中可以使用函数来完成相同的事情。JavaScript中的函数被设计为执行特定任务的代码块&#xff0c;通过关键字function来定义。 <!DOCTYPE html> <html lang"en…

MySQL45讲 第29讲 如何判断一个数据库是不是出问题了?——阅读总结

文章目录 MySQL45讲 第二十九讲 如何判断一个数据库是不是出问题了&#xff1f;——阅读总结一、检测数据库实例健康状态的重要性二、常见检测方法及问题分析&#xff08;一&#xff09;select 1 判断法&#xff08;二&#xff09;查表判断法&#xff08;三&#xff09;更新判断…

IO多路复用(Linux epoll)

文章目录 一、IO多路复用介绍1. 缓存 I/O (各种IO模型缘起) 二、目前有哪些IO多路复用的方案三、关联基础知识1. 用户空间和内核空间2. 文件描述符fd 四、Linux IO多路复用 select五、Linux IO多路复用 epoll1. epoll 介绍2. epoll只提供三个函数ET模式与LT模式 3. demo验证 六…

【数据结构与算法】相交链表、环形链表(判断是否有环)、环形链表(返回入环节点)

主页&#xff1a;HABUO&#x1f341;主页&#xff1a;HABUO &#x1f341;如果再也不能见到你&#xff0c;祝你早安&#xff0c;午安&#xff0c;晚安&#x1f341; 1.相交链表 题目&#xff1a;给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表…

Move 合约部署踩坑笔记:如何解决 Sui 客户端发布错误Committing lock file

Move 共学活动&#xff1a;快速上手 Move 开发 为了帮助更多开发者快速了解和掌握 Move 编程语言&#xff0c;Move 共学活动由 HOH 社区、HackQuest、OpenBuild、KeyMap 联合发起。该活动旨在为新手小白提供一个良好的学习平台&#xff0c;带领大家一步步熟悉 Move 语言&#…

【C语言】野指针问题详解及防范方法

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;什么是野指针&#xff1f;&#x1f4af;未初始化的指针代码示例问题分析解决方法 &#x1f4af;指针越界访问代码示例问题分析解决方法 &#x1f4af;指向已释放内存的…

关于如何在k8s中搭建一个nsfw黄图鉴定模型

随着现在应用内图片越来越多&#xff0c;安全审查也是必不可少的一个操作了 下面手把手教你如何将huggingface中的黄图检测模型部署到自己的服务器上去 1.找到对应的模型 nsfw_image_detection 2.在本地先验证如何使用 首先安装transformers python库 pip install transform…

初学 flutter 环境变量配置

一、jdk&#xff08;jdk11&#xff09; 1&#xff09;配置环境变量 新增&#xff1a;JAVA_HOMEC:\Program Files\Java\jdk-11 //你的jdk目录 在path新增&#xff1a;%JAVA_HOME%\bin2&#xff09;验证是否配置成功&#xff08;cmd运行命令&#xff09; java java -version …

信息安全实验--密码学实验工具:CrypTool

1. CrypTool介绍&#x1f4ad; CrypTool 1的开源教育工具&#xff0c;用于密码学研究。通过CrypTool 1&#xff0c;可以实现加密和解密操作&#xff0c;数字签名。CrypTool1和2有很多区别的。 来源于&#xff1a;网络安全快速入门5-密码学及密码破解工具CrypTool实战_百度知道…

服务器数据恢复—raid5阵列+LVM+VXFS数据恢复案例

服务器存储数据恢复环境&#xff1a; 某品牌MSA2000FC存储中有一组由7块盘组建的RAID5阵列&#xff0c;另外还有1块硬盘作为热备盘使用。 基于RAID5阵列划分的几个LUN分配给小机使用&#xff0c;存储空间通过LVM管理&#xff0c;重要数据为Oracle数据库及OA服务端。 服务器存储…

基于微信小程序的酒店客房管理系统+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、员工、普通用户功能模块&#xff1a;员工管理、用户管理、客房管理、预订管理、商品管理、评价管理、续订管理、订单管理等技术选型&#xff1a;SSM&#xff0c;vue&#xff0c;uniapp等测试环境&#xff1a;idea2024&#xff0c;jdk1…

学习Zookeeper

Zookeeper有手就行 1. 初识ZooKeeper1.1 安装ZooKeeper1.2 ZooKeeper命令操作1.2.1 Zookeeper数据模型1.2.2 Zookeeper 服务端常用命令1.2.3 Zookeeper客户端常用命令 2. ZooKeeperJavaAPl操作2.1 Curator介绍2.2 CuratorAPI常用操作2.2.0 引入Curator支持2.2.1 建立连接2.2.2 …

java基础知识(Math类)

引入&#xff1a;Math 类包含用于执行基本数学运算的方法&#xff0c;如初等指数、对数、平方根 import java.util.Math 1.abs绝对值 int abs Math.abs(-9); 2.pow求幂 double pow Math.pow(2,4); 3.向上取整 double ceil Math.ceil(3.9);//ceil 4 4.向下取整 dou…

【AIGC】大模型面试高频考点-RAG中Embedding模型选型

【AIGC】大模型面试高频考点-RAG中Embedding模型选型 &#xff08;一&#xff09;MTEB排行榜英文模型排名&#xff1a;1、bge-en-icl2、stella_en_1.5B_v53、SFR-Embedding-2_R4、gte-Qwen2-7B-instruct5、stella_en_400M_v56、bge-multilingual-gemma27、NV-Embed-v18、voyage…

学习threejs,使用设置normalMap法向量贴图创建更加细致的凹凸和褶皱

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshPhongMaterial高…

SAP ME2L/ME2M/ME3M报表增强添加字段

SAP ME2L/ME2M/ME3M报表增强添加字段&#xff08;包含&#xff1a;LMEREPI02、SE18:ES_BADI_ME_REPORTING&#xff09; ME2L、ME2M、ME3M这三个报表的字段增强&#xff0c;核心点都在同一个结构里 SE11:MEREP_OUTTAB_PURCHDOC 在这里加字段&#xff0c;如果要加的字段是EKKO、…