当前位置:首页 > 芯闻号 > 充电吧
[导读]简述 为了方便网络编程,Qt 提供了 Network 模块。该模块包含了许多类,例如:QFtp - 能够更加轻松使用 FTP 协议进行网络编程。 但是,从 Qt5.x 之后,Qt Network

简述

为了方便网络编程,Qt 提供了 Network 模块。该模块包含了许多类,例如:QFtp - 能够更加轻松使用 FTP 协议进行网络编程。

但是,从 Qt5.x 之后,Qt Network 发生了很大的变化,助手中关于此部分描述如下:

The QFtp and QUrlInfo classes are no longer exported. Use QNetworkAccessManager instead. Programs that require raw FTP or HTTP streams can use the Qt FTP and Qt HTTP compatibility add-on modules that provide the QFtp and QHttp classes as they existed in Qt 4.

意思是说:不再导出 QFtp 和 QUrlInfo 类,改用 QNetworkAccessManager。

简述开启 FTP 服务效果FtpManager使用更多参考

开启 FTP 服务

Linux 下实现 FTP 服务的软件很多,最常见的有:vsftpd、Wu-ftpd 和 Proftp 等。

访问 FTP 服务器时需要经过验证,只有经过了 FTP 服务器的相关验证,用户才能访问和传输文件。

首先,服务器需要安装 FTP 软件,以 vsftpd 为例:

[root@localhost wang]# which vsftpd
/sbin/vsftpd
1 2

这说明服务器已经安装了 vsftpd,再进行一系列配置即可使用。

关于 FTP 服务的搭建、配置属于 Linux 范畴,这里就不过多赘述了,请自行查看资料。

效果

实现效果如下:

如果要获取更多关于:文件剩余大小、平均速度、瞬时速度 、剩余时间等相关信息,请参考:Qt之HTTP上传/下载

FtpManager

为了便于使用,封装一个简单的 FtpManager 管理类,用于上传、下载文件。

FTPManager.h

#ifndef FTP_MANAGER
#define FTP_MANAGER

#include 
#include 
#include 
#include 

class FtpManager : public QObject
{
    Q_OBJECT

public:
    explicit FtpManager(QObject *parent = 0);
    // 设置地址和端口
    void setHostPort(const QString &host, int port = 21);
    // 设置登录 FTP 服务器的用户名和密码
    void setUserInfo(const QString &userName, const QString &password);
    // 上传文件
    void put(const QString &fileName, const QString &path);
    // 下载文件
    void get(const QString &path, const QString &fileName);

signals:
    void error(QNetworkReply::NetworkError);
    // 上传进度
    void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
    // 下载进度
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);

private slots:
    // 下载过程中写文件
    void finished();

private:
    QUrl m_pUrl;
    QFile m_file;
    QNetworkAccessManager m_manager;
};

#endif // FTP_MANAGER

FTPManager.cpp

#include 
#include "FTPManager.h"

FtpManager::FtpManager(QObject *parent)
    : QObject(parent)
{
    // 设置协议
    m_pUrl.setScheme("ftp");
}

// 设置地址和端口
void FtpManager::setHostPort(const QString &host, int port)
{
    m_pUrl.setHost(host);
    m_pUrl.setPort(port);
}

// 设置登录 FTP 服务器的用户名和密码
void FtpManager::setUserInfo(const QString &userName, const QString &password)
{
    m_pUrl.setUserName(userName);
    m_pUrl.setPassword(password);
}

// 上传文件
void FtpManager::put(const QString &fileName, const QString &path)
{
    QFile file(fileName);
    file.open(QIODevice::ReadOnly);
    QByteArray data = file.readAll();

    m_pUrl.setPath(path);
    QNetworkReply *pReply = m_manager.put(QNetworkRequest(m_pUrl), data);

    connect(pReply, SIGNAL(uploadProgress(qint64, qint64)), this, SIGNAL(uploadProgress(qint64, qint64)));
    connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SIGNAL(error(QNetworkReply::NetworkError)));
}

// 下载文件
void FtpManager::get(const QString &path, const QString &fileName)
{
    QFileInfo info;
    info.setFile(fileName);

    m_file.setFileName(fileName);
    m_file.open(QIODevice::WriteOnly | QIODevice::Append);
    m_pUrl.setPath(path);

    QNetworkReply *pReply = m_manager.get(QNetworkRequest(m_pUrl));

    connect(pReply, SIGNAL(finished()), this, SLOT(finished()));
    connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64, qint64)));
    connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SIGNAL(error(QNetworkReply::NetworkError)));
}

// 下载过程中写文件
void FtpManager::finished()
{
    QNetworkReply *pReply = qobject_cast(sender());
    switch (pReply->error()) {
    case QNetworkReply::NoError : {
        m_file.write(pReply->readAll());
        m_file.flush();
    }
        break;
    default:
        break;
    }

    m_file.close();
    pReply->deleteLater();
}

注释很详细,我就不再多做解释了。。。

注意:下载过程中文件写入是在主线程中进行的,如果文件过大,频繁写入会造成主线程卡顿现象。要避免此种情况,请在工作线程中进行。

使用

这里,只贴主要代码:

// 构建需要的控件
QPushButton *pUploadButton = new QPushButton(this);
QPushButton *pDownloadButton = new QPushButton(this);
m_pUploadBar = new QProgressBar(this);
m_pDownloadBar = new QProgressBar(this);

pUploadButton->setText(QString::fromLocal8Bit("上传"));
pDownloadButton->setText(QString::fromLocal8Bit("下载"));

// 接信号槽
connect(pUploadButton, SIGNAL(clicked(bool)), this, SLOT(upload()));
connect(pDownloadButton, SIGNAL(clicked(bool)), this, SLOT(download()));

// 设置 FTP 相关信息
m_ftp.setHostPort("192.168.***.***", 21);
m_ftp.setUserInfo("wang", "123456");

其中,m_ftp 是类变量 FtpManager。

// 上传文件
void MainWindow::upload()
{
    m_ftp.put("E:\Qt.zip", "/home/wang/Qt.zip");
    connect(&m_ftp, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
    connect(&m_ftp, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)));
}

// 下载文件
void MainWindow::download()
{
    m_ftp.get("/home/wang/Qt.zip", "F:\Qt.zip");
    connect(&m_ftp, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
    connect(&m_ftp, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
}

// 更新上传进度
void MainWindow::uploadProgress(qint64 bytesSent, qint64 bytesTotal)
{
    m_pUploadBar->setMaximum(bytesTotal);
    m_pUploadBar->setValue(bytesSent);
}

// 更新下载进度
void MainWindow::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    m_pDownloadBar->setMaximum(bytesTotal);
    m_pDownloadBar->setValue(bytesReceived);
}

// 错误处理
void MainWindow::error(QNetworkReply::NetworkError error)
{
    switch (error) {
    case QNetworkReply::HostNotFoundError :
        qDebug() << QString::fromLocal8Bit("主机没有找到");
        break;
        // 其他错误处理
    default:
        break;
    }
}

在上传、下载过程中,确保 Server 端的路径存在:

[root@localhost wang]# pwd
/home/wang
[root@localhost wang]# ls
hello.sh
[root@localhost wang]#

上传完成后,可以去 Server 端查看一下:

[root@localhost wang]# ls -l
总用量 52980
-rw-r--r-- 1 root root       20 11月 16 14:01 hello.sh
-rw-r--r-- 1 wang  wang  54246299 11月 16 17:36 Qt.zip
[root@localhost wang]# md5sum Qt.zip 
8d010354447515d55c65d733bbba2682  Qt.zip

源文件 Qt.zip 的大小为 54,246,299 字节,显然,目标文件也一样(可使用 MD5 比对,看文件是否损坏),这说明已经完全上传成功了。

更多参考

Qt之HTTP上传/下载原文链接:http://blog.csdn.net/liang19890820/article/details/53188182

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

摘 要 :为解决制鞋行业中喷胶精度不高、灵活性差、生产效率低的问题,设计一种基于机器视觉的鞋模喷胶系统。该系统硬件由工业摄像头、工控机及路由器构成,软件则采用图像识别库 OpenCV 与图形界面应用程序开发框架 Qt 编...

关键字: 机器视觉 图像处理 鞋模 喷胶 OpenCV QT

嵌入式系统是指以应用为中心、以计算机技术为基础,软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。

关键字: QT 嵌入式 C++

摘 要:仓储作为物流与供应链的核心环节,对食品安全的控制起着至关重要的作用。温湿度是影响粮食仓储过程安全与品质的重要因素。文中使用无线传感网络进行数据采集,通过Qt平台设计软件系统,并借助数据库进行数据存储与分析处理,实...

关键字: 成品粮 仓储 温湿度监测 无线传感网络 QT

在此部件上绘制行号,并将其放置在CodeEditor的viewport()的左边距区域上,QWidget类也可以帮助我们对其内容进行滚动。

关键字: QT 代码编辑器

不管是Qt新手还是开发过qt的群体来说,对Qt Designer、Qt Quick Designer、Qt Creator这几个应用程序肯定是熟悉的。

关键字: QT IDE C

在当今社会,人们的生活水平普遍提高,工作强度越来越大,营养的过剩和运动量的减少,导致心脑血管疾病的发病率是越来越高。

关键字: Linux QT GPRS 远程集群式 心脏病人实时诊断系

qt值得学习吗? 嵌入式要学的东西真的很多,我们可能会说不写界面的话就不用学qt了?我不赞同。

关键字: 嵌入式 QT UI

什么是qt?简单点说,Qt 就是一个跨平台的 C++ 图形用户界面库,可以同时支持桌面应用程序开发、嵌入式开发和移动开发,覆盖了现有的所有主流平台。

关键字: QT 程序 开发

qt值得学习吗? 嵌入式要学的东西真的很多,我们可能会说不写界面的话就不用学qt了?我不赞同,原因是……

关键字: 嵌入式 QT

摘要Qt是欧洲人创始的一个优秀的C++开发框架,API简单易用,社区庞大,资源丰富;但Qt太重量级了(需要很多的RAM和ROM,非常复杂)。为了解决这个问题,我开发了GOSP这个框架。GOSP在不依赖

关键字: QT 开发
关闭
关闭