关于Qt **QNetworkAccessManager**、**QNetworkReply**、**QNetworkRequest**实现ftp下载时,**QNetworkReply**::**downloadProgress**信号的**bytesTotal**一直为-1的原因分析

实现的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。解决方案不优雅,但是可行。

posted @   thammer  阅读(169)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示