基于QT的FTP客服端Syncftp

简述

Syncftp客户端基于Qt(Qt4或者Qt5都可以)的跨平台的FTP客户端,由于Qt4和Qt5对ftp支持有区别,为了代码统一,就选择了ftplib库作为ftp模块。

下载地址:https://download.csdn.net/download/no2101/12386832

设计

  • 界面设计

界面分为菜单栏、工具栏、主界面和状态栏。

  •   站点管理设计

  1. 新建站点

  1. 打开站点管理,即可看到新建的站点,双击即可登录。

  1.  

FTP管理类设计

FTP管理类为:class FtpTransfer

  1. 具体代码:

//FtpTransfer.h代码
#ifndef FTPTRANSFER_H
#define FTPTRANSFER_H

#include <QObject>
#include <QFileInfoList>
#include <QDir>
#include <QTextCodec>
#include <QFileInfo>
#include "3rdparty/ftplib/ftplib.h"

struct REMFILE {
    struct REMFILE *next;
    fsz_t fsz;
    char *fnm;
};



class FtpTransfer : public QObject
{
    Q_OBJECT
public:
    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 <QThread>

#include <QDebug>



#ifdef _WIN32

#include <Windows.h>

#else

#include <sys/stat.h>

#include <unistd.h>

#endif



static 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 \n", f->fnm, pct,xfered);

    }else{

        printf("%s %d \n", 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()<<"Getfile2"<<sts;

    if (sts)

        printf("%s retrieved\n", local_file);

}



void FtpTransfer::PutFile2(const QString &local_file_str  , const QString& remote_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();



    int sts = FtpPut(local_file, remote_file, 'I', pftp_conn);

    if (sts)

        printf("%s sent\n", 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;

    else

        total_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\n", Ba2.constData(), FtpLastResponse(pftp_conn));

        return;

    }

    QStringList dir_dir;

    while (FtpRead(buf, 1024, tempdir) > 0){

        char *p = strchr(buf, '\n');

        if (p)*p = '\0';

        QString Dir_verbose = codec->toUnicode(buf);

        QStringList  list1  = Dir_verbose.split(' ',QString::SkipEmptyParts);

        QString _name;

        for(int i=8;i<list1.size();i++){

            _name.append(list1.at(i));

            if(i+1<list1.size())

                _name.append(" ");

        }



        QString _attribute = list1.at(0);

        if(!_attribute.left(1).compare("d")){

            dir_dir<<_name;

        }else{

            total_list<<total_dir+"/"+_name;

        }

    }

    FtpClose(tempdir);

    FtpChdir(ftp_path,pftp_conn);



    for(int i=0;i<dir_dir.size();i++){

        GetFtpDirFiles(total_dir,dir_dir.at(i),total_list);

    }

}





void FtpTransfer::GetDir(const QString &ftp_path,const QString &ftp_dir,const QString &local_dir)

{

    QStringList slist;

    GetFtpDirFiles(ftp_path,ftp_dir,slist);

    for(int i=0;i<slist.size();i++)

    {

        //qDebug()<<i<<ftp_path<<ftp_dir<<slist.at(i);

        QString info = slist.at(i);

        int lbak=0;

        if(ftp_path.compare("/")!=0)

            lbak=1;

        QString temp = info.right(info.length()-ftp_path.length()-lbak);

        QStringList dirlist1 = temp.split('/');

        QDir ldir(local_dir);

        for(int j=0;j<dirlist1.size()-1;j++)

        {

            if(!ldir.cd(dirlist1.at(j))){

                ldir.mkdir(dirlist1.at(j));

                ldir.cd(dirlist1.at(j));

            }

        }

        ldir.cd(local_dir);

        Getfile2(info,local_dir+"/"+temp);

    }

    emit Transferfinish(QString::fromLocal8Bit("下载文件夹%1完成").arg(ftp_dir));

}







void FtpTransfer::PutFile(const QString &local_file_str  , const QString& remote_file_str )

{

    PutFile2(local_file_str  , remote_file_str );

    emit Transferfinish(QString::fromLocal8Bit("上传文件%1完成").arg(local_file_str));

}



void FtpTransfer::FindDirFiles(const QString& path, QFileInfoList& total_list)

{

    QDir dir(path);

    dir.setFilter(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::NoSymLinks);

    dir.setSorting(QDir::Name|QDir::DirsFirst);

    QFileInfoList infolist = dir.entryInfoList();

    foreach(QFileInfo info,infolist){

        if(info.isDir()){

            FindDirFiles(info.filePath(),total_list);

        }else{

            total_list.append(info);

        }

    }

}

void FtpTransfer::PutDir(const QString &ftp_dir,const QString &dir)

{

    QByteArray ba = codec->fromUnicode(ftp_dir);

    const char *path = ba.constData();

    QFileInfoList dir_files_list;

    FindDirFiles(dir,dir_files_list);

    for(int i=0;i<dir_files_list.size();i++)

    {

        QFileInfo info = dir_files_list.at(i);

        QString fullpath = info.path();

        QString temp = fullpath.right(fullpath.length()-dir.lastIndexOf("/")-1);

        QStringList dirlist1 = temp.split('/');



        for(int j=0;j<dirlist1.size();j++){

            QByteArray Ba        = codec->fromUnicode(dirlist1.at(j));

            const char *dir_path = Ba.constData();

            int sts = FtpChdir(dir_path, pftp_conn);

            //            qDebug()<<dirlist1.at(j)<<sts<<ftp_dir;

            if(sts != 1){

                FtpMkdir(dir_path, pftp_conn);

                FtpChdir(dir_path, pftp_conn);

            }

        }

        PutFile2(info.filePath(),info.fileName());

        FtpChdir(path,pftp_conn);

    }



    emit Transferfinish(QString::fromLocal8Bit("上传文件夹%1完成").arg(dir));

}

​

 

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);

 

服务器字符编码

服务器的字符编码是由服务器决定的,一般的中文windows平台字符编码是GBK,而Linux平台为UTF8

如果没有设置正确字符,则有乱码。

  • 测试

  • 搭建ftp服务器

Linux下可以安装vsftpd,Windows下可以使用FileZilla_Server等。具体搭建方法可以到网上查一下。

  • 新建站点

  1. 链接站点

双击即可登录

  • 上传下载,鼠标右键

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于Qt实现的FTP程序是一种用于文件传输的网络应用程序。Qt是一个跨平台的开发框架,可以帮助开发者简化程序编写过程并实现不同操作系统下的程序兼容性。 FTP通过用户操作,可以连接到FTP,并进行文件的上传和下载操作。FTP程序提供了用户界面,包括登录信息的输入、文件列表的展示以及上传下载按钮等。用户可以通过FTP上传本地文件到FTP务器,或者从FTP务器下载文件到本地。上传、下载的过程中,FTP会与FTP进行交互,通过FTP协议进行数据传输。 FTP程序则负责接收FTP的连接,处理的请求,并根据请求进行文件的上传和下载。FTP通过监听指定的口号,等待的连接请求。一旦有的连接请求,接受连接,并通过鉴权确认的身份。程序接收的上传请求后,将文件保存在务器指定的位置;接收的下载请求后,从务器指定位置读取文件并发送给。 基于QtFTP程序可以实现跨平台的文件传输功能,提供了图形化的用户界面和方便的操作方式。科研工作者、程序员、企业等可以使用FTP程序,方便地在不同设备之间进行文件传输,提高工作效率。此外,通过FTP的鉴权机制,可以保证文件传输的安全性,更好地满足用户的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天之豹_top

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值