基于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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是基于Qt制作服务器和客户的步骤: 1. 首先,需要安装Qt开发环境。可以从Qt官网下载安装包,然后按照提示进行安装。 2. 创建一个新的Qt项目,选择"Qt Widgets Application",然后在下一个页面中选择"Server",并设置项目名称和路径。 3. 在项目中添加服务器代码。可以在Qt Creator中创建一个新的类,然后编写服务器代码。服务器代码需要监听客户的连接请求,接收客户发送的消息,并将消息转发给其他客户。 4. 使用Qt Designer来设计服务器的界面。可以添加一些控件,如按钮、文本框等,用于显示服务器的状态和接收客户的输入。 5. 在服务器代码中添加逻辑,将控件和代码进行连接。例如,当点击"启动服务器"按钮时,调用服务器代码中的启动函数。 6. 创建一个新的Qt项目,选择"Qt Widgets Application",然后在下一个页面中选择"Client",并设置项目名称和路径。 7. 在项目中添加客户代码。可以在Qt Creator中创建一个新的类,然后编写客户代码。客户代码需要连接服务器,并发送和接收消息。 8. 使用Qt Designer来设计客户的界面。可以添加一些控件,如按钮、文本框等,用于显示客户的状态和输入消息。 9. 在客户代码中添加逻辑,将控件和代码进行连接。例如,当点击"连接服务器"按钮时,调用客户代码中的连接函数。 10. 最后,在Linux环境下,需要使用命令行界面来测试这个即时聊天工具。可以打开多个终窗口,分别运行服务器和不同的客户,并且在客户之间发送消息进行测试。 以上是一个基本的实现方案,具体实现细节还需要根据具体的需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值