• 6536阅读
  • 4回复

[讨论]为QFtp类添加断点下载的功能 [复制链接]

上一主题 下一主题
离线渡世白玉
 

只看楼主 倒序阅读 楼主  发表于: 2013-12-01
我用的是QFtp For Qt5的独立版本,Qt4好像也能用。
先说FTP断点下载的原理:
第一,最重要的一点,断点续传需要服务器的支持,这个是必要条件。
传统的FTP SERVER是不支持断点续传的,因为它不支持REST指令,传统的FTP指令(我是指服务器端指令)并不包括REST指令。
第二,客户端要知道使用REST等一系列指令来作断点续传。
看看断点续传的详细过程(FTP SERVER):
首先客户端使用REST指令来告诉FTP SERVER它需要从文件的某个点开始传,接着用STOR或者RETR命令开始传文件,大概的命令的流程如下:
TYPE I
200 Type set to I.
PASV
227 Entering Passive Mode (204,48,18,69,98,250)
REST 187392
350 Restarting at 187392. Send STORE or RETRIEVE to initiate transfer.
RETR /pub/audio/pci/maestro-3/win2k/1056.zip
150 Opening BINARY mode data connection for /pub/audio/pci/maestro-3/win2k/1056.zip (936098 bytes).
首先使用TYPE命令告诉FTP SERVER使用BINARY模式传送文件;
然后使用PASV命令告诉FTP SERVER使用被动打开模式来传送文件;
接着使用REST 187392指令告诉FTP SERVER要从文件的187392字节开始传送;
最后使用RETR指令来传送文件。
从上面可以看出,这个FTP SERVER支持REST指令,有的FTP SERVER(特别的老的)是不支持这个指令的,这时即使FTP CLIENT支持断点续传也一点用都没有
支持断点的FTP SERVER:Serv-U FTP,还有一系列的新出现的FTP SERVER;
不支持断点的:IIS4以前版本所带的都不行,IIS5 有,不家可以测试一下,登录进FTP SERVER,然后输入REST 1000命令,看服务器是否认识,认识就是支持断点。
现在最新的ftp服务器软件应该几乎都支持的、、
下面说下改动:
QFtp类里是get函数实现的下载,get原型是: int get(const QString &file, QIODevice *dev=0, TransferType type = Binary);
file是你要下载的文件名,Dev是你要保存的文件,可以不写的,那样默认是缓存到内存的,可以通过readAll()函数获取下载的内容的、、
TransferType传输模式,默认是二进制、、
为了实现断点,我们要用REST告诉服务器我们要从哪儿开始下载,这需要对这个函数动下手脚,你可以新建一个重载,我为了省事直接添加了哥默认值:我更改后原型:int get(const QString &file, QIODevice *dev=0, qulonglong size = 0, TransferType type = Binary);
添加一个size参数,无符号长整型的、、并默认值为0,接着就需要在函数主体里实现了、、照的get函数的实现:
先贴上全部的实现:
int QFtp::get(const QString &file, QIODevice *dev, qulonglong size, TransferType type)
{
    QStringList cmds;
    if (type == Binary)
        cmds << QLatin1String("TYPE I\r\n");
    else
        cmds << QLatin1String("TYPE A\r\n");
    cmds << QLatin1String("SIZE ") + file + QLatin1String("\r\n");
    cmds << QLatin1String(d->transferMode == Passive ? "PASV\r\n" : "PORT\r\n");
    if (size > 0)
    {
        cmds << QLatin1String("REST ") + QString::number(size) + QLatin1String("\r\n");//添加REST命令
    }
    cmds << QLatin1String("RETR ") + file + QLatin1String("\r\n");     return d->addCommand(new QFtpCommand(Get, cmds, dev));
}
其中:

if (size > 0)
    {
        cmds << QLatin1String("REST ") + QString::number(size) + QLatin1String("\r\n");//添加REST命令
    }
是我添加的,逻辑很简单,当size设置为0的时候,不断点下载,大于0就启用断点下载、、不启用就设置为0就行了、、
还有查询某个文件大小,原来准备加个函数实现,最后发现QFtp类允许运行自己的命令就没加,因为ftp查询文件大小用SIZE命令,但是原来有ftp服务器不支持、、
用rawCommand(“SIZE 文件名”)函数得到文件大小
我的例子:https://github.com/dushibaiyu/MyQtExample/tree/master/QFtpSeriesDown


大家可以支持下我blog,本文源地址:http://www.dushibaiyu.com/2013/11/为qftp类添加断点下载的功能.html
离线loopolike

只看该作者 1楼 发表于: 2013-12-19
怎么下载啊
离线loopolike

只看该作者 2楼 发表于: 2013-12-19
很多这种错误啊
离线davie

只看该作者 3楼 发表于: 2014-01-02

http://www.qtcn.org/bbs/read-htm-tid-55698.html 出现编译问题,请问如何解决?
离线渡世白玉

只看该作者 4楼 发表于: 2014-01-03
基于QT5 +C++11的\\用mingw请在工程文件添加参数 CONFIG+= C++11
快速回复
限100 字节
 
上一个 下一个