实现的ftp下载需要反馈下载进度,但是代码得到的bytesTotal始终为-1,直到下载完成那一刻,才变成文件大小。于是分析qt5base的network部分代码:
network/access/qnetworkaccessftpbackend.cpp文件中,有如下片段:
void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text)
{
//qDebug() << "FTP reply:" << code << text;
int id = ftp->currentId();
if ((id == helpId) && ((code == 200) || (code == 214))) { // supported commands
// the "FEAT" ftp command would be nice here, but it is not part of the
// initial FTP RFC 959, neither ar "SIZE" nor "MDTM" (they are all specified
// in RFC 3659)
if (text.contains(QLatin1String("SIZE"), Qt::CaseSensitive))
supportsSize = true;
if (text.contains(QLatin1String("MDTM"), Qt::CaseSensitive))
supportsMdtm = true;
if (text.contains(QLatin1String("PWD"), Qt::CaseSensitive))
supportsPwd = true;
} else if (id == pwdId && code == 257) {
QString pwdPath;
int startIndex = text.indexOf('"');
int stopIndex = text.lastIndexOf('"');
if (stopIndex - startIndex) {
// The working directory is a substring between \" symbols.
startIndex++; // skip the first \" symbol
pwdPath = text.mid(startIndex, stopIndex - startIndex);
} else {
// If there is no or only one \" symbol, use all the characters of
// text.
pwdPath = text;
}
此处它通过SITE help命令查询ftp server支持的命令,我这边ftp server是pureftpd,实际在终端用ftp命令连接上后,site help查询得到的结果确实没有SIZE的支持,尝试通过配置文件看能否打开此命令的支持,但是每查到,于是阅读pureftpd源码,src/ftp_parser.c
中可知,site help
得到的返回永远是固定的,
else if (!strcasecmp(arg, "help")) {
help_site:
addreply_noformat(214, MSG_SITE_HELP CRLF
# ifdef WITH_DIRALIASES
" ALIAS" CRLF
# endif
" CHMOD" CRLF " IDLE" CRLF " UTIME");
addreply_noformat(214, "Pure-FTPd - http://pureftpd.org/");
}
于是只好暴力修改Qt源码,QNetworkAccessFtpBackend构造的初始化列表将
QNetworkAccessFtpBackend::QNetworkAccessFtpBackend()
: ftp(nullptr), uploadDevice(nullptr), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1),
supportsSize(true), supportsMdtm(false), supportsPwd(false), state(Idle)
{
}
supportsSize(false) 改为true.问题解决,不过对应的ftp server那端必须要支持size命令,好在ftp server大多一般都支持size。解决方案不优雅,但是可行。
标签:ftp,QNetworkRequest,help,text,startIndex,QNetworkReply,true,Qt From: https://www.cnblogs.com/thammer/p/17478789.html