按照前文《qt实现ftp上传与下载》介绍的方法实现文件的上传和下载后,单个文件的上传或者下载确实没问题。
但是在走流程测试时,如果客户端程序一直开启,上传之后再进行文件的下载时,程序就直接 crash 了;或者在当前文件上传后,再上传另一个文件,也会导致程序 crash,且都是必然现象。
初始上传、下载代码分别如下:
// ftp 上传
void ClassName::uploadRemoteHost(const QString &upload_file)
{
...
QString host = QString("127.0.0.1");
ftp.connectToHost(host, 21);
connect(&ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(uploadHandleFinish(int, bool)));
...
return;
}
void ClassName::uploadHandleFinish(int id, bool error)
{
...
}
// ftp 下载
void ClassName::downloadRemoteHost()
{
...
QString host = QString("127.0.0.1");
ftp.connectToHost(host, 21);
connect(&ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(downloadHandleFinish(int, bool)));
...
return;
}
void ClassName::downloadHandleFinish(int id, bool error)
{
...
}
其中, uploadHandleFinish() 和 downloadHandleFinish() 都是自定义的方法,做些接收信号时的一些处理。
可以看到这两个方法都是绑定了 QFtp 的信号器 commandFinish(int, bool) ,也就是说,当两个方法都相继调用 connect() 绑定之后,后面再有 ftp 的任何操作,uploadHandleFinish() 和 downloadHandleFinish() 俩方法都会收到并做相应的处理;或者在第一次上传某个文件之后再上传时,会再做一次绑定,触发 uploadHandleFinish() 方法多次调用。这两种情况经实测后都会导致程序的 crash。
为了避免多次绑定信号器,可以利用 connect() 方法的第五个参数,当设置为 Qt::UniqueConnection 时,程序就可以正常使用了。即:
// ftp 上传绑定
connect(&ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(uploadHandleFinish(int, bool)), Qt::UniqueConnection);
// ftp 下载绑定
connect(&ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(downloadHandleFinish(int, bool)), Qt::UniqueConnection);
理论上来说,还可以在声明对象时就绑定,而不是等到上传、下载时才开始绑定。这样应该也能保证信号器方法只绑定一次,欢迎感兴趣的小伙伴测试~