使用Qt实现FTP客户端

2 篇文章 0 订阅
2 篇文章 0 订阅

头文件ftp.h

#pragma once
#ifdef CREATEDELL_API_DU
#else
#define  CREATEDELL_API_DU  _declspec(dllexport)
#endif

#ifndef FTPCLIENT_H

#include <QtCore\QString>
#include <QtNetwork\QNetworkAccessManager>
#include <QtNetwork\QNetworkRequest>
#include <QtNetwork\QNetworkReply>
#include <QtCore\QUrl>
#include <QtCore\QFile>
#include <QtCore\QDir>
#include <QtCore\QDebug>
#include <QtCore\QObject>

#include <memory>




class CREATEDELL_API_DU FtpClient : public QObject
{
    Q_OBJECT

public:
    explicit FtpClient(QObject *parent = 0);
    virtual ~FtpClient();
    void setUrl();
    void setDir(const QString& dirpath);
    void setFile(QString& filename);
    void setPort(int port = 21);
    void setPath(QString& path);
    void setHost(QString& ip);
    void setPassword(QString& password);
    void setUserName(QString& username);
    void setPercent(qint64 bytesSent, qint64 bytesTotal);
    QNetworkReply::NetworkError getErrorCode();
    void FtpClient::setErrorCode(QNetworkReply::NetworkError errors);
public slots:
    void upload();
    void download(int& errCode);
    void readContent();
    void replyFinished(QNetworkReply*);
    void loadError(QNetworkReply::NetworkError);
    void loadProgress(qint64 bytesSent, qint64 bytesTotal);
    
public:
    virtual void onFinish() {}
    virtual qint64 getPersent() 
    { 
        return percent_; 
    }


private:
    QNetworkReply *reply_;
    std::shared_ptr<QFile> file_;
    std::shared_ptr<QUrl> url_;
    std::shared_ptr<QDir> dir_;
    std::shared_ptr<QNetworkAccessManager> accessManager_;
    qint64 percent_;
    QNetworkReply::NetworkError error_;
};

#endif // FTPCLIENT_H

 源文件ftp.cpp

#define CREATEDELL_API_DU _declspec(dllexport)

#include "ftp.h"

#include <iostream>
#include <QEventLoop>

CREATEDELL_API_DU FtpClient::FtpClient(QObject *parent) :
    QObject(parent), percent_(0)

{
    url_ = std::make_shared<QUrl>();
    url_->setScheme("ftp");
}


CREATEDELL_API_DU FtpClient::~FtpClient()
{

}


QNetworkReply::NetworkError FtpClient::getErrorCode()
{
    return this->error_;
}

void FtpClient::setErrorCode(QNetworkReply::NetworkError errors)
{
    this->error_ = errors;
}


void CREATEDELL_API_DU FtpClient::setDir(const QString& dirPath)
{
    dir_ = std::make_shared<QDir>(dirPath);
    if (!dir_->exists())
    {
        auto ok = dir_->mkdir(dirPath);
        if (!ok)
        {
            qDebug() << "make dir " << dirPath << " failed..." << endl;
        }
    }
}
void CREATEDELL_API_DU FtpClient::setUrl()
{
    url_ = std::make_shared<QUrl>();
    url_->setScheme("ftp");
}

void CREATEDELL_API_DU FtpClient::setFile(QString& fileName)
{
    file_ = std::make_shared<QFile>(dir_->absolutePath() + "/" + fileName);
}


void CREATEDELL_API_DU FtpClient::setPort(int port)
{
    if (nullptr != url_)
    {
        url_->setPort(port);
    }
}


void CREATEDELL_API_DU  FtpClient::setPercent(qint64 sendBytes, qint64 totalBytes)
{
    double result = 100.0 * sendBytes / totalBytes;
    this->percent_ = (int)result;
}


void CREATEDELL_API_DU FtpClient::setPassword(QString& password)
{
    if (nullptr != url_)
    {
        url_->setPassword(password);
    }
}


void CREATEDELL_API_DU FtpClient::setUserName(QString& userName)
{
    if (nullptr != url_)
    {
        url_->setUserName(userName);
    }
}


void CREATEDELL_API_DU FtpClient::setPath(QString& path)
{
    url_->setPath(path);
}


void CREATEDELL_API_DU FtpClient::setHost(QString& ip)
{
    url_->setHost(ip);
}


void CREATEDELL_API_DU FtpClient::upload()
{

    qDebug() << "upload file " << *file_ << " begin..." << endl;
    if (!file_->open(QIODevice::ReadOnly))
    {
        qDebug() << "open file " << *file_ << " failed..." << endl;
    }
    //创建一个QNetworkAccessManager实例,将accessManager指向它
    accessManager_ = std::make_shared<QNetworkAccessManager>(this);
    accessManager_->setNetworkAccessible(QNetworkAccessManager::Accessible);

    QNetworkRequest request(*url_);
    reply_ = accessManager_->put(request, file_.get());
    
    connect(accessManager_.get(), SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)),Qt::DirectConnection);
    connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)),Qt::DirectConnection);
    connect(reply_, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(loadProgress(qint64, qint64)),Qt::DirectConnection);
}


void CREATEDELL_API_DU FtpClient::download(int& errCode)
{
    errCode = 0;
    qDebug() << "download file " << *file_ << " begin..." << endl;
    file_->open(QIODevice::WriteOnly);  

    accessManager_ = std::make_shared<QNetworkAccessManager>(this);
    accessManager_->setNetworkAccessible(QNetworkAccessManager::Accessible);
    
    QNetworkRequest request(*url_);
    reply_ = accessManager_->get(request);

    connect(reply_, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
            [=, &errCode](QNetworkReply::NetworkError code)
    {
        file_->close();
        switch ((int)code)
        {
        case QNetworkReply::ConnectionRefusedError:
            qDebug() << "ConnectionRefusedError";
            break;
        case QNetworkReply::HostNotFoundError:
            qDebug() << "HostNotFoundError";
            break;
        case QNetworkReply::TimeoutError:
            qDebug() << "TimeoutError";
            break;
        case QNetworkReply::AuthenticationRequiredError:
        {
            qDebug() << "AuthenticationRequiredError";
            errCode = code;
            break;
        }
        default:
        {
            errCode = code;
            break;
        }
        }
    });

    connect((QObject *)reply_, SIGNAL(readyRead()), this, SLOT(readContent()));
    connect((QObject*)(accessManager_.get()), SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)),Qt::DirectConnection);
    //connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)),Qt::DirectConnection);
    connect(reply_, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(loadProgress(qint64, qint64)),Qt::DirectConnection);

    QEventLoop eventloop;
    connect((QObject*)(accessManager_.get()), SIGNAL(finished(QNetworkReply*)), &eventloop, SLOT(quit()));
    eventloop.exec(QEventLoop::ExcludeUserInputEvents);
}


void CREATEDELL_API_DU FtpClient::readContent()
{
    file_->write(reply_->readAll());
}


void CREATEDELL_API_DU FtpClient::replyFinished(QNetworkReply* replys)
{
    if (reply_->error() == QNetworkReply::NoError)
    {
        qDebug() << "end..." << endl;
        reply_->deleteLater();
        file_->flush();
        file_->close();
		
		//发送传输完成信号
        onFinish();
    }
    else
    {
        //QMessageBox::critical(NULL, tr("Error"), "Failed!!!");
        qDebug() << "Error Failed!!!" << endl;
    }
}



void CREATEDELL_API_DU FtpClient::loadError(QNetworkReply::NetworkError)
{
    qDebug() << "Error: " << reply_->error();
    setErrorCode( reply_->error());
}


void CREATEDELL_API_DU FtpClient::loadProgress(qint64 bytesSend, qint64 bytesTotal)
{
    setPercent(bytesSend, bytesTotal);
    qDebug() << "loaded" << bytesSend << "of" << bytesTotal << "  " << getPersent() << "%";
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值