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

文章目录

  • 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.comServerAdmin webmaster@localhostDocumentRoot /var/www/html<Directory  "/var/www/html">Dav onOptions Indexes FollowSymLinks MultiViewsAllowOverride AllRequire all grantedallow 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.passwordAuthBasicProvider file# 允许userfile.pass里的所有用户访问       Require valid-userAllowOverride 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_NAMESPACEclass MainInterface : public QMainWindow
{Q_OBJECTpublic: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.mzph.cn/bicheng/62424.shtml

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

相关文章

JVM 常见面试题及解析(2024)

目录 一、JVM 基础概念 二、JVM 内存结构 三、类加载机制 四、垃圾回收机制 五、性能调优 六、实战问题 七、JVM 与其他技术结合 八、JVM 内部机制深化 九、JVM 相关概念拓展 十、故障排查与异常处理 一、JVM 基础概念 1、什么是 JVM&#xff1f;它的主要作用是…

自动化运维(k8s)之微服务信息自动抓取:namespaceName、deploymentName等全解析

前言&#xff1a;公司云原生k8s二开工程师发了一串通用性命令用来查询以下数值&#xff0c;我想着能不能将这命令写成一个自动化脚本。 起初设计的 版本一&#xff1a;开头加一条环境变量&#xff0c;执行脚本后&#xff0c;提示输入&#xff1a;需要查询的命名空间&#xff0c…

鸿蒙一次开发,多端部署,响应式布局

鸿蒙一次开发&#xff0c;多端部署&#xff0c;响应式布局 一、定义屏幕相关常量 BreakpointConstants.ets import BreakpointType from ../bean/BreakpointType export default class BreakPointConstants{/*** 小屏幕设备的Breakpoints 标记*/static readonly BREAKPOINT_…

ubuntu防火墙入门(一)——设置服务、关闭端口

本机想通过git clone gitgithub.com:skumra/robotic-grasping.git下载代码&#xff0c;firewall-config中需要为当前区域的防火墙开启SSH服务吗 是的&#xff0c;如果你想通过 git clone gitgithub.com:skumra/robotic-grasping.git 使用 SSH 协议从 GitHub 下载代码&#xff0…

springboot332基于springboot养老院管理系统pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 养老院管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计…

js:函数

函数 函数&#xff1a;实现抽取封装&#xff0c;执行特定任务的代码块&#xff0c;方便复用 声明 函数命名规范 尽量小驼峰 前缀应该为动词&#xff0c;如getName、hasName 函数的调用 函数体是函数的构成部分 函数传参 参数列表里的参数叫形参&#xff0c;实际上写的数据叫实…

基于Matlab的图像去噪算法仿真

中值滤波的仿真 本节选用中值滤波法对含有高斯噪声和椒盐噪声的图像进行去噪&#xff0c;并用Matlab软件仿真。 &#xff08;1&#xff09;给图像加入均值为0&#xff0c;方差为0.02的高斯噪声&#xff0c;分别选择33模板、55模板和77模板进行去噪 Matlab部分代码&#xff1…

前端网络安全分析

前端常见的网络安全包括&#xff1a;xss&#xff08;跨站脚本攻击&#xff09;、csrf&#xff08;跨站请求伪造&#xff09;、sql注入攻击等。 1&#xff09;跨站脚本攻击&#xff08;xss&#xff09; 原理&#xff1a; 攻击者往web页面中注入恶意 script 代码&#xff08;或…

【Linux】-学习笔记06

第二章、时间同步服务器 2.1时间同步服务器的使用 2.1.1系统时区时间的管理 timedatectl set-time "2024-02-13 10:41:55" ##设定系统时间 timedatectl list-timezones ##显示系统的所有时区 timedatectl set-timezone "Asia/Shangh…

UE5_建立自己的资产库

资产库需要用到一个插件&#xff1a; UAsset Browser - 直接在当前项目预览其他UE项目资产&#xff08;.uasset 文件&#xff09; - 直接迁移其他UE项目资产到当前项目 - 不用另外打开资产项目查看资产&#xff0c;迁移资产&#xff08;麻烦&#xff09; 插件官网插件文档插…

macOS 桌面悬浮窗口

开发一个 macOS 桌面悬浮窗口(类似悬浮工具条、任务管理器等)可以使用 macOS 的 AppKit 框架,通过配置窗口属性,使窗口始终显示在其他应用窗口的上方。以下是开发的详细步骤: 关键点 窗口类型 使用 NSWindow 创建悬浮窗口。将窗口设置为浮动窗口,使其始终显示在其他窗口上…

GitLab/GitHub 多环境配置SSH密钥

需求&#xff1a; 代码有多个仓库&#xff0c;需要配置不同的密钥。 生成密钥&#xff08;有的可以跳过&#xff09; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" -f ~/.ssh/id_rsa_custom_name-t rsa 指定使用 RSA 算法。-b 4096 指定密钥长度为 4096 位…

力扣整理版十:动态规划(待更新)

动态规划&#xff1a;每一个状态由上一个状态推导出来。 --------------------------- (1) 509 斐波那契数 (2) 70 爬楼梯 (3) 746 使用最小花费爬楼梯 --------------------------- 一、基础题目 1、509 斐波那契数 509. 斐波那契数 - 力扣&#xff08;LeetCode&#…

黑马2024AI+JavaWeb开发入门Day02-JS-VUE飞书作业

视频地址&#xff1a;哔哩哔哩 讲义作业飞书地址&#xff1a;飞书 一、作业1 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">&l…

详解登录MySQL时出现SSL connection error: unknown error number错误

目录 登录MySQL时出错SSL connection error: unknown error number 出错原因 使用MySQL自带的工具登录MySQL 登陆之后&#xff0c;使用如下命令进行查看 解决方法 找到MySQL8安装目录下的my.ini配置文件 记事本打开my.ini文件&#xff0c;然后按下图所示添加配置 此时再…

深度学习基本单元结构与输入输出维度解析

深度学习基本单元结构与输入输出维度解析 在深度学习领域&#xff0c;模型的设计和结构是理解其性能和应用的关键。本文将介绍深度学习中的基本单元结构&#xff0c;包括卷积神经网络&#xff08;CNN&#xff09;、反卷积&#xff08;转置卷积&#xff09;、循环神经网络&…

Sofia-SIP 使用教程

Sofia-SIP 是一个开源的 SIP 协议栈&#xff0c;广泛用于 VoIP 和即时通讯应用。以下是一些基本的使用教程&#xff0c;帮助你快速上手 Sofia-SIP。 1. 安装 Sofia-SIP 首先&#xff0c;你需要安装 Sofia-SIP 库。你可以从其官方 GitHub 仓库克隆源代码并编译安装&#xff1a…

【八股文】小米

文章目录 一、vector 和 list 的区别&#xff1f;二、include 双引号和尖括号的区别&#xff1f;三、set 的底层数据结构&#xff1f;四、set 和 multiset 的区别&#xff1f;五、map 和 unordered_map 的区别&#xff1f;六、虚函数和纯虚函数的区别&#xff1f;七、extern C …

【leetcode100】找到字符串中所有字母异位词

1、题目描述 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s "cbaebabacd", p "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "…

乐鑫发布 esp-iot-solution v2.0 版本

今天&#xff0c;乐鑫很高兴地宣布&#xff0c;esp-iot-solution v2.0 版本已经发布&#xff0c;release/v2.0 分支下的正式版本组件将为用户提供为期两年的 Bugfix 维护&#xff08;直到 2027.01.25 ESP-IDF v5.3 EOL&#xff09;。该版本将物联网开发中常用的功能进行了分类整…