利用QT通过http协议,来实现上传文件功能

#假如你有一台服务器,你最想做哪些事?#

大体上的软件界面如下:

利用QT通过http协议,来实现上传文件功能_第1张图片

主要阐述一哈写的这个软件实现的功能:

通过名称找到指定的文件,并且将文件按照后缀名的格式进行分开,最后再将所有找到的文件,进行上传到目标服务器的指定位置。

为了实现上述功能,一共采用了一下内容:

利用python搭建了一个简易的服务器,用来模拟接收上传文件的接口。

利用QT5.15.2写了一个软件,这个软件包含软件界面,和配置ini文件。

在这里主要是想讲一哈python如何实现服务器的搭建。

第一种是在cmd命令里面写:

python -m http.server

默认是打开的8000的端口

第二种是写一个简单的python的代码来实现服务器的功能

具体代码如下:

from http.server import BaseHTTPRequestHandler, HTTPServer
import os
import urllib.parse


# 定义HTTP请求处理类
class FileUploadHandler(BaseHTTPRequestHandler):
    # 处理POST请求
    def do_POST(self):
        # 解析Content-Length头部,获取上传文件大小
        content_length = int(self.headers['Content-Length'])
        # 解析Content-Disposition头部,获取上传文件名
        cd_header = self.headers.get('Content-Disposition')
        filename = urllib.parse.unquote(cd_header)

        # 读取上传的文件数据
        file_data = self.rfile.read(content_length)

        # 保存上传的文件
        with open(filename, 'wb') as f:
            f.write(file_data)

            # 设置响应状态码为200,表示成功接收文件
        self.send_response(200)
        self.end_headers()
    def do_GET(self):
        if self.is_first_request:
            self.is_first_request = False
            for k in dir(self):
                v = getattr(self, k)
                # 魔术方法,私有变量和大部分的callable并不是为我们提供的,所以排除
                if k.startswith('_') or callable(v):
                    continue
                print('---arg: ', k, ' type:', v.__class__.__name__, '\n', v, '\n\n', sep='')



server = HTTPServer(('localhost', 8080), FileUploadHandler)
print('Server started on port 8080...')

# 进入请求处理循环
server.serve_forever()

在上述代码中,我们创建了一个名为FileUploadHandler的HTTP请求处理类,并覆盖了do_POST方法以处理POST请求。在do_POST方法中,我们获取上传文件的大小,读取文件数据,我们增加了对Content-Disposition头部的解析,从中获取上传文件的文件名。然后,我们使用获取到的文件名保存上传的文件,从而保持原文件名不变。需要注意的是,为了避免文件名中包含特殊字符导致的问题,我们使用urllib.parse.unquote函数对文件名进行URL解码。然后,我们设置响应状态码为200,表示成功接收文件。最后,我们创建了一个HTTP服务器实例,并启动服务器以监听来自localhost的8080端口的请求。

另外值得一提的是:

搭建一个服务器需要以下要素:

  1. 硬件设备:包括计算机、硬盘、内存、网卡等。计算机应具备足够的内存以处理大量数据和多个连接,如果需要支持多个网站或许多并发连接,可能需要更大的内存。硬盘空间应足够大,以存储操作系统文件、网页文件、数据库和其他必要的文件。网卡则需要能够处理多个网络连接。
  2. 操作系统:应选择适合自己服务器的操作系统,常见的服务器操作系统包括Windows Server、Linux和Unix。
  3. 环境搭建部署:包括选择熟悉的环境,选择数据库以及应用中间件。
  4. 网站应用部署:创建新的网站应用,并配置为本地自己的网站应用目录。
  5. 网站发布:启用解析映射,添加映射。

然后就是在QT里面写上传文件的代码部分

实现的具体代码如下所示:

QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);//定义multi的方式
    // 创建一个QNetworkAccessManager对象,用于处理网络请求
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);


    QString uploadFileName = directory+"/"+goal;//获取文件路径
    qDebug()<open(QIODevice::ReadOnly);
    QHttpPart filePart;
    filePart.setBodyDevice(file);
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant( QFileInfo(filePath).fileName() ));
    multiPart->append(filePart);

    // 创建一个QNetworkReply对象,用于接收上传的响应
    QNetworkReply *reply = manager->post(request, multiPart);

    // 连接QNetworkReply的信号,以处理上传的响应数据
    connect(reply, &QNetworkReply::finished, this, [=]() {
        if (reply->error() == QNetworkReply::NoError) {
            // 上传成功,处理响应数据
        QString response = reply->readAll();
            qDebug()<<"成功"<errorString();
        }
        // 清理资源
        reply->deleteLater();
        multiPart->deleteLater();
        file->deleteLater();
    });
  1. QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);:创建一个QHttpMultiPart对象,用于构建多部分表单数据,以便进行文件上传。
  2. QNetworkAccessManager *manager = new QNetworkAccessManager(this);:创建一个QNetworkAccessManager对象,它是Qt中用于处理网络请求的核心类。
  3. QString uploadFileName = directory+"/"+goal;:根据目录和文件名拼接出要上传的文件的完整路径。
  4. qDebug()<:输出上传文件的路径和HTTP地址,用于调试。
  5. QNetworkRequest request(http);:创建一个QNetworkRequest对象,使用指定的HTTP地址。
  6. QFile *file = new QFile(filePath);:创建一个QFile对象,打开要上传的文件。
  7. file->open(QIODevice::ReadOnly);:以只读模式打开文件。
  8. QHttpPart filePart;:创建一个QHttpPart对象,用于表示文件数据部分。
  9. filePart.setBodyDevice(file);:将文件设置为QHttpPart的body部分。
  10. filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QFileInfo(filePath).fileName()));:设置QHttpPart的头部信息,包括文件名。
  11. multiPart->append(filePart);:将文件数据部分添加到QHttpMultiPart对象中。
  12. QNetworkReply *reply = manager->post(request, multiPart);:使用QNetworkAccessManager对象发送POST请求,将QHttpMultiPart对象作为请求体,并获取响应。
  13. connect(reply, &QNetworkReply::finished, this, [=]() {...});:连接QNetworkReply对象的finished信号,当上传完成时,执行Lambda函数处理响应数据。

在Lambda函数中,首先检查上传是否成功,如果成功,读取响应数据并进行处理;如果失败,输出错误信息。最后清理资源,删除replymultiPartfile对象。

这段代码实现了基本的文件上传功能,通过Qt的网络模块发送HTTP请求,并将文件作为请求体上传到服务器。

你可能感兴趣的:(python,qt,服务器)