C++使用Poco库封装一个FTP客户端类

0x00 Poco库中 Poco::Net::FTPClientSession

Poco库中FTP客户端类是 Poco::Net::FTPClientSession , 该类的接口比较简单。

  1. 上传文件接口: beginUpload() , endUpload()
  2. 下载文件接口: beginDownload() , endDownload()

0x01 FTPCli类说明

  • FTPCli类实现了连接FTP服务器,断开连接,上传文件和下载文件。
  • 下载文件有两个接口,第一个接口从FTP服务器下载文件使用FTP服务器中的文件名,第二个接口是一个重载函数,可以将需要下载文件重新命名。

0x02 FTPCli类代码

#ifndef FTPCLI_H
#define FTPCLI_H

#include <Poco/Poco.h>
#include <Poco/Exception.h>
#include <Poco/Net/FTPClientSession.h>
#include <string>

class FTPCli
{
public:
    FTPCli(const std::string &host, const unsigned short port, const std::string &user, const std::string &passwd);
    ~FTPCli();

    bool Connect(int retryCount = 3);
    void DisConnect();

    bool UploadFile(const std::string &localFilePath, const std::string &remoteFilePath);
    bool DownloadFile(const std::string &remoteFile);
    bool DownloadFile(const std::string &remoteFile, const std::string &localFile);

private:
    Poco::Net::FTPClientSession m_ftpSession;
    std::string m_host;
    unsigned short m_port;
    std::string m_user;
    std::string m_passwd;
};

#endif // FTPCLI_H

#include "ftpcli.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <Poco/Path.h>

FTPCli::FTPCli(const std::string &host, const unsigned short port, const std::string &user, const std::string &passwd)
    : m_host(host), m_port(port), m_user(user), m_passwd(passwd)
{
    char ftpUrl[128];
    sprintf(ftpUrl, "ftp://%s:%s@%s:%d/", m_user.c_str(), m_passwd.c_str(),
            m_host.c_str(), m_port);
    printf("[%s:%d] %s\n", __FILE__, __LINE__, ftpUrl);
}

FTPCli::~FTPCli()
{
    DisConnect();
}

bool FTPCli::Connect(int retryCount)
{
    while (retryCount > 0)
    {
        try
        {
            if (!m_ftpSession.isOpen())
            {
                m_ftpSession.open(m_host, m_port);
            }

            if (!m_ftpSession.isLoggedIn())
            {
                m_ftpSession.login(m_user, m_passwd);
            }

            printf("WorkingDirectory: %s\n", m_ftpSession.getWorkingDirectory().c_str());
            printf("%s\n", m_ftpSession.welcomeMessage().c_str());

            return true;
        }
        catch (Poco::Exception &ex)
        {
            printf("Error connecting to FTP server: %s\n", ex.what());

            --retryCount;
            if (retryCount > 0)
            {
                char errlog[128];
                sprintf(errlog, "ftp://%s:%s@%s:%d/", m_user.c_str(), m_passwd.c_str(),
                        m_host.c_str(), m_port);

                printf("Retrying connect %s...\n", errlog);
            }
        }
    }

    // throw std::runtime_error("Failed to connect to FTP server after multiple attempts.");
    return false;
}

void FTPCli::DisConnect()
{
    try
    {
        if (m_ftpSession.isOpen())
        {
            m_ftpSession.close();
        }
    }
    catch (Poco::Exception &ex)
    {
        printf("Error: %s\n", ex.what());
    }
}

bool FTPCli::UploadFile(const std::string &localFilePath, const std::string &remoteFilePath)
{
    try
    {
        // 设置FTP服务器的工作目录
        m_ftpSession.setWorkingDirectory(remoteFilePath);

        std::ifstream inFile(localFilePath, std::ios::in);
        if (!inFile.is_open())
        {
            printf("Failed to open file: %s\n", localFilePath.c_str());
            return false;
        }

        Poco::Path tmpPath(localFilePath);
        std::string tmpFileName = tmpPath.getBaseName();
        printf("[%s:%d] FileBaseName: %s\n", __FILE__, __LINE__, tmpFileName.c_str());

        auto &res = m_ftpSession.beginUpload(tmpFileName);

        std::string line;
        while (std::getline(inFile, line))
        {
            res << line;
        }
        inFile.close();

        m_ftpSession.endUpload();
    }
    catch (const Poco::Exception &ex)
    {
        printf("Error connecting to FTP server: %s\n", ex.displayText().c_str());
        m_ftpSession.endUpload();
        return false;
    }

    return true;
}

bool FTPCli::DownloadFile(const std::string &remoteFile)
{
    try
    {
        std::ofstream outFile(remoteFile, std::ios::out | std::ios::app);
        if (!outFile.is_open())
        {
            printf("Failed to open file: %s\n", remoteFile.c_str());
            return false;
        }

        auto &res = m_ftpSession.beginDownload(remoteFile);

        std::string line;
        while (std::getline(res, line))
        {
            outFile << line;
        }
        outFile.close();

        m_ftpSession.endDownload();
    }
    catch (const Poco::Exception &ex)
    {
        printf("Error: %s\n", ex.displayText().c_str());
        m_ftpSession.endDownload();
        return false;
    }

    return true;
}

bool FTPCli::DownloadFile(const std::string &remoteFile, const std::string &localFile)
{
    try
    {
        std::ofstream outFile(localFile, std::ios::out | std::ios::app);
        if (!outFile.is_open())
        {
            printf("Failed to open file: %s\n", localFile.c_str());
            return false;
        }

        auto &res = m_ftpSession.beginDownload(remoteFile);

        std::string line;
        while (std::getline(res, line))
        {
            outFile << line;
        }
        outFile.close();

        m_ftpSession.endDownload();
    }
    catch (const Poco::Exception &ex)
    {
        printf("Error: %s\n", ex.displayText().c_str());
        m_ftpSession.endDownload();
        return false;
    }

    return true;
}

0x03 使用介绍

在这里插入图片描述

C++ Poco库同样可以轻松的实现SFTP客户端和TFTP客户端。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晓琴儿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值