为QFtp类添加断点下载的功能

我用的是QFtp For Qt5的独立版本。

先说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 Irn");
    else
        cmds << QLatin1String("TYPE Arn");
    cmds << QLatin1String("SIZE ") + file + QLatin1String("rn");
    cmds <transferMode == Passive ? "PASVrn" : "PORTrn");
    if (size > 0)
    {
        cmds << QLatin1String("REST ") + QString::number(size) + QLatin1String("rn");//添加REST命令
    }
    cmds <addCommand(new QFtpCommand(Get, cmds, dev));
}

其中:

 if (size > 0)
    {
        cmds << QLatin1String("REST ") + QString::number(size) + QLatin1String("rn");//添加REST命令
    }

是我添加的,逻辑很简单,当size设置为0的时候,不断点下载,大于0就启用断点下载、、不启用就设置为0就行了、、

还有查询某个文件大小,原来准备加个函数实现,最后发现QFtp类允许运行自己的命令就没加,因为ftp查询文件大小用SIZE命令,但是原来有ftp服务器不支持、、

用rawCommand(“SIZE 文件名”)函数得到文件大小

我的例子:https://github.com/dushibaiyu/DsbyLiteExample/tree/master/QFtpSeriesDown

评论已关闭。