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

news2024/11/15 21:25:02

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客户端。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker(六)-本地镜像发布到私有库

1.下载镜像Docker Registry 用于搭建私人版本Docker Hub docker pull registry2.运行私有库Registry 运行私有库Registry&#xff0c;相当于本地有个私有Docker hubdocker run -d -p hostPort:containerPort -v 【宿主机目录】:【容器目录】 --privilegedtrue 【私有库镜像】…

群晖NAS部署VoceChat私人聊天系统并一键发布公网分享好友访问

文章目录 前言1. 拉取Vocechat2. 运行Vocechat3. 本地局域网访问4. 群晖安装Cpolar5. 配置公网地址6. 公网访问小结 7. 固定公网地址 前言 本文主要介绍如何在本地群晖NAS搭建一个自己的聊天服务Vocechat&#xff0c;并结合内网穿透工具实现使用任意浏览器远程访问进行智能聊天…

PS添加物体阴影

一、选择背景&#xff0c;确保物体和北京分割出图层 二、右键单击物体图层&#xff0c;点击混合选项&#xff0c;点击投影 三、调整参数&#xff0c;可以看效果决定(距离是高度&#xff0c;扩展是浓度&#xff0c;大小是模糊程度)&#xff0c;保存即可

dp经典问题:LCS问题

dp&#xff1a;LCS问题 最长公共子序列&#xff08;Longest Common Subsequence, LCS&#xff09;问题 是寻找两个字符串中最长的子序列&#xff0c;使得这个子序列在两个字符串中出现的相对顺序保持一致&#xff0c;但不要求连续。 力扣原题链接 1.定义 给定两个字符串 S1…

Apple - Game Center Programming Guide

本文翻译整理自&#xff1a;Game Center Programming Guide&#xff08; Updated: 2016-06-13 https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/GameKit_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008304 文章…

什么是zip格式?zip格式文件要怎么打开,一文详解

Zip是一种常见的压缩文件格式&#xff0c;广泛应用于文件和文件夹的打包和压缩。它的使用方便、文件体积小&#xff0c;是网络传输和存储文件时的常用选择。本文将深入介绍Zip格式的定义、特点以及它在现代计算机应用中的重要性。 zip是什么文件&#xff1f; ZIP是一种相当简单…

专业竞赛组织平台赛氪网,引领大学生竞赛新时代

随着互联网技术的快速发展&#xff0c;高校学科竞赛组织和管理正迎来新的变革。环球赛乐&#xff08;北京&#xff09;科技有限公司&#xff08;以下简称”赛氪网“&#xff09;&#xff0c;作为一家专业竞赛组织平台不仅致力于大学生成长和前途的拓展&#xff0c;更在推动学科…

【Android】Android Studio 使用Kotlin写代码时代码提示残缺问题解决

问题描述 Android Studio升级之后&#xff0c;从Android Studio 4.2升级到Android Studio Arctic Fox版本&#xff0c;因为项目比较老&#xff0c;使用的Gradle 版本是3.1.3&#xff0c;这个版本的Android Studio最低支持Gradle 3.1版本&#xff0c;应该算是比较合适的版本。 …

【Redis】如何保证缓存和数据库的一致性

目录 背景问题思路 三个经典的缓存模式Cache-Aside读缓存写缓存为什么是删除旧缓存而不是更新旧缓存&#xff1f;为什么不先删除旧的缓存&#xff0c;然后再更新数据库&#xff1f; 延迟双删如何确保原子性 Read-Through/Write-ThroughRead-ThroughWrite-Through Write Behind …

LINUX桌面运维----第一天

一、Linux的特点&#xff1a; &#xff08;1&#xff09;与UNIX兼容 &#xff08;2&#xff09;自由软件&#xff0c;源码公开 &#xff08;3&#xff09;性能高&#xff0c;安全性强 &#xff08;4&#xff09;便于定制和再开发 &#xff08;5&#xff09;相互之间操作性…

某同盾验证码

⚠️前言⚠️ 本文仅用于学术交流。 学习探讨逆向知识&#xff0c;欢迎私信共享学习心得。 如有侵权&#xff0c;联系博主删除。 请勿商用&#xff0c;否则后果自负。 网址 aHR0cHM6Ly9zZWMueGlhb2R1bi5jb20vb25saW5lRXhwZXJpZW5jZS9zbGlkaW5nUHV6emxl 1. 先整体分析一下接…

地级市绿色创新及碳排放与环境规划数据(2000-2021年)

数据简介&#xff1a;分享各个城市对于碳排放的降低做出了哪些共享。该数据是地级市2000-2021年间由绿色创新、碳排放与环境规制数据构成的能源与环境研究数据大合集&#xff0c;并对其进行可视化处理&#xff0c;供大家研究使用。当今我国大力推进生态文明建设、美丽中国建设等…

【Python系列】FastAPI 中的路径参数和非路径参数解析问题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

PDF秒变翻页式电子画册

​在当今数字化时代&#xff0c;将PDF文档转换成翻页式电子画册是一种提升作品展示效果和传播效率的有效方式。以下是将PDF秒变翻页式电子画册的攻略&#xff0c;帮助您轻松掌握数字创作技巧。 首先&#xff0c;选择一个合适的制作工具是关键。目前市场上有多种在线平台和软件可…

元素旋转?一个vue指令搞定

说在前面 &#x1f388;鼠标控制元素旋转功能大家应该都不陌生了吧&#xff0c;今天我们一起来看看怎么编写一个vue指令来实现元素旋转功能吧&#xff01; 效果展示 体验地址 http://jyeontu.xyz/jvuewheel/#/JRotateView 实现思路 1、自定义指令对象 export default {inse…

选择门店收银系统要考虑哪些方面?美业系统Java源码分享私

开店前的一个重要事件就是选择门店收银软件/系统&#xff0c;尤其是针对美容、医美等美业门店&#xff0c;一个优秀专业的系统十分重要&#xff0c;它必须贴合门店的经营需求&#xff0c;提供更全面、便捷、高效的管理功能&#xff0c;帮助提升门店的服务质量和经营效益。 以下…

品牌策划背后的秘密:我为何对此工作情有独钟?

你是否曾有过一个梦想&#xff0c;一份热爱&#xff0c;让你毫不犹豫地投身于一个行业&#xff1f; 我就是这样一个对品牌策划充满热情的人。 从选择职业到现在&#xff0c;我一直在广告行业里“混迹”&#xff0c;一路走来&#xff0c;也见证了许多对品牌策划一知半解的求职…

CPsyCoun:心理咨询多轮对话自动构建及评估方法

CPsyCoun: A Report-based Multi-turn Dialogue Reconstruction and Evaluation Framework for Chinese Psychological Counseling 在大模型应用于心理咨询领域&#xff0c;目前开源的项目有&#xff1a; https://github.com/SmartFlowAI/EmoLLM &#xff08;集合&#xff0c;…

mp4转换成mp3怎么转?教你几种值得收藏的转换方法!

mp4转换成mp3怎么转&#xff1f;MP4&#xff0c;这一深入人心的数字多媒体容器格式&#xff0c;无疑在当今数字世界中占据了一席之地&#xff0c;那么&#xff0c;它究竟有何过人之处呢&#xff1f;首先&#xff0c;MP4的跨平台兼容性是其一大亮点&#xff0c;不论是在Windows的…

(一)、配置服务器的多个网卡路由,访问多个不同网络段

一、现场网络关系说明 有这么一个需要&#xff0c;服务器有三个网口&#xff0c;网口一需要访问外网&#xff0c;网口二需要访问内网1&#xff0c;网口2需要访问内网2。需要配置路由来满足该网络访问需要。 图1 现场网络关系 二、配置教程 步骤1&#xff1a; a、命令行输入…