简述
Syncftp客户端基于Qt(Qt4或者Qt5都可以)的跨平台的FTP客户端,由于Qt4和Qt5对ftp支持有区别,为了代码统一,就选择了ftplib库作为ftp模块。
下载地址:https://download.csdn.net/download/no2101/12386832
如有不妥,欢迎指正。
设计
2.1. 界面设计
界面分为菜单栏、工具栏、主界面和状态栏。
2.2. 站点管理设计
a) 新建站点
b) 打开站点管理,即可看到新建的站点,双击即可登录。
2.3. FTP管理类设计
FTP管理类为:class FtpTransfer
a) 具体代码:
//FtpTransfer.h代码
#ifndef FTPTRANSFER_H#define FTPTRANSFER_H#include #include #include #include #include #include "3rdparty/ftplib/ftplib.h"struct REMFILE {struct REMFILE *next;fsz_t fsz;char *fnm;};class FtpTransfer : public QObject{Q_OBJECTpublic:FtpTransfer(QObject *parent = 0);void SetNetBuf(netbuf *conn){pftp_conn = conn;}void SetTextCodec(QTextCodec *_codec){codec=_codec;}void GetFtpDirFiles(const QString& path, const QString &dir,QStringList& total_list);void Getfile2(const QString& remote_file , const QString &local_file);void FindDirFiles(const QString& path, QFileInfoList& total_list);void PutFile2(const QString &local_file , const QString& remote_file );signals:void Transferfinish(const QString &msg);public slots:void Getfile(const QString& remote_file , const QString &local_file);void GetDir(const QString &ftp_path,const QString &ftp_dir,const QString &local_dir);void PutFile(const QString &local_file , const QString& remote_file );void PutDir(const QString &ftp_dir,const QString &local_dir);private:netbuf *pftp_conn;QTextCodec *codec;};#endif // FTPTRANSFER_H
//FtpTransfer.cpp代码
#include "FtpTransfer.h"#include #include #ifdef _WIN32#include #else#include #include #endifstatic int log_progress(netbuf *ctl, fsz_t xfered, void *arg){struct REMFILE *f = (struct REMFILE *) arg;if (f->fsz){double pct = (xfered * 100.0) / f->fsz;printf("%s %5.2f%% %d ", f->fnm, pct,xfered);}else{printf("%s %d ", f->fnm, xfered);}fflush(stdout);return 1;}FtpTransfer::FtpTransfer(QObject *parent) : QObject(parent){pftp_conn = NULL;}void FtpTransfer::Getfile2(const QString &remote_file_str , const QString &local_file_str){QByteArray Ba = codec->fromUnicode(remote_file_str);char *remote_file = Ba.data();QByteArray Ba2 = local_file_str.toLocal8Bit();char *local_file = Ba2.data();unsigned int fsz = 0;struct REMFILE f;f.next = NULL;f.fnm = remote_file;if (FtpSize(remote_file, &fsz, 'I', pftp_conn) == 0)fsz = 0;f.fsz = fsz;fsz /= 100;if (fsz > 100000)fsz = 100000;if (fsz == 0)fsz = 32768;FtpCallbackOptions opt;opt.cbFunc = log_progress;opt.cbArg = &f;opt.idleTime = 1000;opt.bytesXferred = fsz;FtpSetCallback(&opt, pftp_conn);int sts = FtpGet(local_file, remote_file, 'I', pftp_conn);qDebug()<fromUnicode(remote_file_str);char *remote_file = Ba.data();QByteArray Ba2 = local_file_str.toLocal8Bit();char *local_file = Ba2.data();int sts = FtpPut(local_file, remote_file, 'I', pftp_conn);if (sts)printf("%s sent", local_file);}void FtpTransfer::Getfile(const QString &remote_file_str , const QString &local_file_str){Getfile2(remote_file_str ,local_file_str);emit Transferfinish(QString::fromLocal8Bit("下载文件%1完成").arg(remote_file_str));}/*** 得到ftp服务器文件夹下的目录*/void FtpTransfer::GetFtpDirFiles(const QString& path,const QString &dir, QStringList& total_list){QByteArray ba1 = codec->fromUnicode(path);const char *ftp_path = ba1.constData();QString total_dir = path;if(path.compare("/")==0)total_dir = total_dir + dir;elsetotal_dir = total_dir + "/" + dir;QByteArray Ba2 = codec->fromUnicode(total_dir);FtpChdir(Ba2.constData(),pftp_conn);netbuf *tempdir = NULL;char buf[1024];if (!FtpAccess(Ba2.constData(), FTPLIB_DIR_VERBOSE, FTPLIB_ASCII, pftp_conn, &tempdir)) {printf("error requesting directory of %s-->%s", Ba2.constData(), FtpLastResponse(pftp_conn));return;}QStringList dir_dir;while (FtpRead(buf, 1024, tempdir) > 0){char *p = strchr(buf, '');if (p)*p = '0';QString Dir_verbose = codec->toUnicode(buf);QStringList list1 = Dir_verbose.split(' ',QString::SkipEmptyParts);QString _name;for(int i=8;ifromUnicode(ftp_dir);const char *path = ba.constData();QFileInfoList dir_files_list;FindDirFiles(dir,dir_files_list);for(int i=0;ifromUnicode(dirlist1.at(j));const char *dir_path = Ba.constData();int sts = FtpChdir(dir_path, pftp_conn);// qDebug()<
b) FtpTransfer使用
QThread* ftpThread = new QThread(this);ftptransfer = new FtpTransfer();ftptransfer->moveToThread(ftpThread);ftptransfer->thread()->start();connect(this,SIGNAL(signal_Connect()),this,SLOT(RootFTP()));connect(this,SIGNAL(signal_connecterror(int)),this,SLOT(ConnectError(int)));connect(this,SIGNAL(signal_GetFile(QString,QString)),ftptransfer,SLOT(Getfile(QString,QString)),Qt::QueuedConnection);connect(this,SIGNAL(signal_GetDir(QString,QString,QString)),ftptransfer,SLOT(GetDir(QString,QString,QString)),Qt::QueuedConnection);connect(this,SIGNAL(signal_PutFile(QString,QString)),ftptransfer,SLOT(PutFile(QString,QString)),Qt::QueuedConnection);connect(this,SIGNAL(signal_PutDir(QString,QString)),ftptransfer,SLOT(PutDir(QString,QString)),Qt::QueuedConnection);connect(ftptransfer,SIGNAL(Transferfinish(QString)),this,SLOT(UpdateFtpDir(QString)),Qt::QueuedConnection);
2.4. 服务器字符编码
服务器的字符编码是由服务器决定的,一般的中文windows平台字符编码是GBK,而Linux平台为UTF8
如果没有设置正确字符,则有乱码。
测试
a) 搭建ftp服务器
Linux下可以安装vsftpd,Windows下可以使用FileZilla_Server等。具体搭建方法可以到网上查一下。
b) 新建站点
c) 链接站点
双击即可登录
d) 上传下载,鼠标右键