QT上位机作为FTP客户端上传多文件

目录

前言

一、FTP协议简介

[1.1 什么是FTP?](#1.1 什么是FTP?)

[1.2 主要特点](#1.2 主要特点)

二、QNetworkAccessManager介绍

1.核心三要素

2.基本工作流程

三、代码实现

[1.创建QNetworkAccessManager 实例](#1.创建QNetworkAccessManager 实例)

2.写FTP文件上传函数

3.在点击事件中调用FTP上传函数

总结


前言

在工业自动化、数据采集和远程监控系统中,经常需要将本地文件上传到远程服务器。FTP(文件传输协议)作为一种经典的文件传输解决方案,仍然被广泛应用于各种场景。本文将详细介绍如何使用QT框架开发一个功能完善的FTP客户端上位机,实现可靠的文件上传功能。

一、FTP协议简介

1.1 什么是FTP?

FTP(File Transfer Protocol,文件传输协议) 是用于在网络上进行文件传输的一套标准协议,属于TCP/IP协议族中的应用层协议。它于1971年由Abhay Bhushan提出,是最早的互联网协议之一,至今仍在广泛使用。

1.2 主要特点

  • 双向传输:支持上传(Upload)和下载(Download)

  • 跨平台性:几乎支持所有操作系统

  • 可靠性:基于TCP,确保数据传输的可靠性

  • 用户管理:支持匿名访问和用户认证

  • 目录操作:支持文件列表、目录创建/删除等操作

二、QNetworkAccessManager介绍

QNetworkAccessManager 是 Qt Network 模块的核心类,用于统一管理网络请求(HTTP/FTP/HTTPS/FTPS 等),提供异步、跨平台的网络通信能力。它遵循 "管理器 - 请求 - 回复" 的设计模式,一个 QNetworkAccessManager 实例可处理多个网络请求,无需为每个请求创建新实例,是 Qt 中实现网络通信的首选方案。

1.核心三要素

作用
QNetworkAccessManager 管理器:创建 / 发送请求、管理连接池、分发回复
QNetworkRequest 请求:封装请求地址(URL)、请求头、SSL 配置、超时等参数
QNetworkReply 回复:封装响应数据、状态码、响应头、错误信息,提供数据读取 / 进度监听

2.基本工作流程

复制代码
1. 创建 QNetworkAccessManager 实例(全局唯一即可);
2. 构建 QNetworkRequest,设置 URL、请求头、SSL 等参数;
3. 调用 manager 的方法(get/put/post 等)发送请求,返回 QNetworkReply 实例;
4. 关联 QNetworkReply 的信号(finished/progress/errorOccurred)处理结果;
5. 请求完成后,手动释放 QNetworkReply(deleteLater()),避免内存泄漏。

三、代码实现

1.创建QNetworkAccessManager 实例

全局变量: QNetworkAccessManager *manager;

在构造器中 manager = new QNetworkAccessManager(this);

2.写FTP文件上传函数

cpp 复制代码
void mainwindow::uploadFtpFile(){
    if(fileQueue.isEmpty()){
        printInfo(ui->print_textEdit,"上传完成",QColor(0,128,0));
        return;
    }
    currentFile=fileQueue.dequeue();
    QFile *file = new QFile("config/"+FtpPath+"/"+currentFile);
    if (!file->open(QIODevice::ReadOnly)) {
        FtpSuccess=false;
        printInfo(ui->print_textEdit,currentFile+"上传失败:找不到参数文件",Qt::red);
        delete file;
        uploadFtpFile();
        return;
    }
    QUrl url("ftp://"+PlatformIp+"/root/"+currentFile);
    if (!FtpUserName.isEmpty() && !FtpPassword.isEmpty()) {
        url.setUserName(FtpUserName);
        url.setPassword(FtpPassword);
    }

    QNetworkRequest request(url);

    // 开始上传
    reply = manager->put(request, file);
    file->setParent(reply); // 文件对象由reply管理
    connect(reply, &QNetworkReply::finished,
            this, &mainwindow::onFinished);

}

void mainwindow::onFinished()
{
    if (reply->error() != QNetworkReply::NoError) {
         FtpSuccess=false;
         printInfo(ui->print_textEdit,currentFile+"上传失败: "+reply->errorString(),Qt::red);
    }
    reply->deleteLater();
    reply->abort();
    reply=nullptr;
    uploadFtpFile();
}

3.在点击事件中调用FTP上传函数

cpp 复制代码
void mainwindow::on_pushButton_clicked()
{
    //判断网络有没有连接上
    if(net_flag==0){
         QMessageBox::information(this,"提示","请先连接平台后再上传参数");
         return;
    }
    int replays;
    replays=QMessageBox::question(this,"确认","您确定需要上传参数吗?",QMessageBox::Yes,QMessageBox::No);
    if(replays==QMessageBox::No){
        return;
    }
    if(!fileQueue.isEmpty()){
        QMessageBox::information(this,"提示","当前正在上传参数,请稍候");
        return;
    }
    for(int i=0;i<FtpFileList.size();i++){
        fileQueue.enqueue(FtpFileList.at(i));
    }
    printInfo(ui->print_textEdit,"正在上传参数文件...",Qt::black);
    FtpSuccess=true;
    uploadFtpFile();
}

FTP上传多文件整体思路就是将要上传的文件名放到一个字符串的队列中,发送完成一个就在队列里面再取一个文件,直到队列里面为空以后,就判断发送完成了,注意发送完了要清一下reply。

reply->deleteLater();

reply->abort();

reply=nullptr;

本地的文件路径是 QFile *file = new QFile("config/test.txt");

上传后的文件路径是 QUrl url("ftp://"192.168.0.22"/root/test.txt");

根据自己需要上传的文件名拼接即可。

字符串队列使用的时候需要调用 #include <QQueue>库,

然后初始化 QQueue<QString> fileQueue。

使用的时候,currentFile=fileQueue.dequeue();即可从队列中拿出第一个字符串并从队列中清除。

fileQueue.enqueue(FtpFileList.at(i));可以给队列增加一个字符串元素。

总结

QT实现FTP的文件上传还是比较简单的,主要是把逻辑理清就可以了,还有一个问题就是如果FTP服务器连接不上的话,会一直请求上传,不会到完成的槽函数中,也不会到报错的槽函数中,因为我是先用TCP连接的服务器再用FTP上传文件,我这里没有做超时处理,QT5.15及以上可以用manager->setTransferTimeout(5000);设置超时,QT5.15以下需要自己写一个超时的倒计时函数,这里就不再详细写了。

相关推荐
屿筱1 小时前
vscode 关于C/C++的环境配置
c++·ide·vscode
luoyayun3611 小时前
Qt/QML 实现类似Xmind简易思维导图绘制
qt·xmind·思维导图
九天轩辕1 小时前
基于 Qt 和 libimobiledevice 的跨平台 iOS 设备管理工具开发实践
开发语言·qt·ios
程序喵大人1 小时前
C++ MCP 服务器实现
开发语言·c++·项目·mcp服务器
小尧嵌入式1 小时前
QT软件开发知识点流程及文本转语音工具
开发语言·c++·qt
MessiGo1 小时前
Bézier 曲线
c++
艾莉丝努力练剑1 小时前
【C++:智能指针】没有垃圾回收?智能指针来也!破解C++内存泄漏:智能指针原理、循环引用与线程安全详解
大数据·运维·c++·安全·编辑器·智能指针
fie88891 小时前
Qt对Word网页的读写功能实现
开发语言·qt·word
橘子真甜~2 小时前
C/C++ Linux网络编程9 - TCP服务器实现流程和独立运行
linux·运维·服务器·c++·守护进程·会话组