0x00 Poco库中 Poco::Net::FTPClientSession
Poco库中FTP客户端类是 Poco::Net::FTPClientSession , 该类的接口比较简单。
- 上传文件接口: beginUpload() , endUpload()
- 下载文件接口: 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客户端。