news 2026/5/15 17:23:50

C++:FTP文件上传下载(附带源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++:FTP文件上传下载(附带源码)

项目背景详细介绍

在传统企业系统、工业控制、内网工具以及大量遗留系统中,FTP(File Transfer Protocol)依然被广泛用于文件传输任务,例如:

  • 自动化日志上传

  • 程序更新文件分发

  • 服务器配置同步

  • 内网设备文件交换

  • 嵌入式系统文件传输

尽管如今 HTTP / HTTPS 已成为主流,但在以下场景中 FTP 仍不可替代:

  • 内网环境,部署简单

  • 老系统兼容性要求高

  • 无需复杂证书配置

  • 与大量历史系统对接

对于C++ 开发者而言,掌握 FTP 文件传输能力,依然是系统工具开发、运维工具、工业软件中的重要技能。

在 Windows 平台上,微软提供了成熟稳定的WinINet API,用于:

  • HTTP / HTTPS

  • FTP

  • 代理网络访问

无需引入第三方库,即可完成 FTP 登录、上传、下载等操作,非常适合教学与工程实践。

因此,本项目将通过一个完整、可运行、工程级的 C++ 示例,系统演示:

如何使用 C++ + WinINet 实现 FTP 文件上传与下载

该项目非常适合作为 Windows 网络编程、系统工具开发、C++ 实战课程的教学案例


项目需求详细介绍

1. 功能需求

  1. 使用 C++ 连接 FTP 服务器

  2. 支持用户名 / 密码登录

  3. 支持文件上传(PUT)

  4. 支持文件下载(GET)

  5. 支持二进制模式传输

  6. 输出关键执行步骤日志

2. 技术要求

  1. 基于 Windows 原生 WinINet API

  2. 使用 FTP 被动模式

  3. 支持 Unicode(宽字符)

  4. 不依赖任何第三方库

3. 教学与工程要求

  1. 明确区分 FTP 会话与连接

  2. 展示完整 FTP 操作流程

  3. 代码结构清晰、可复用

  4. 适合课堂逐步讲解


相关技术详细介绍

1. FTP 协议简介

FTP 是一种基于 TCP 的明文文件传输协议,主要包含:

  • 控制连接(端口 21)

  • 数据连接(主动 / 被动模式)

基本操作包括:

  • 登录(USER / PASS)

  • 上传(STOR)

  • 下载(RETR)

  • 列表(LIST)


2. WinINet API 简介

WinINet 是 Windows 提供的高层网络 API,封装了:

  • Socket 细节

  • 协议交互流程

  • 错误处理机制

常用 FTP 相关函数包括:

  • InternetOpen

  • InternetConnect

  • FtpPutFile

  • FtpGetFile

  • InternetCloseHandle


3. FTP 传输模式

本项目采用:

  • 二进制模式(FTP_TRANSFER_TYPE_BINARY)

  • 被动模式(PASV)

这是最常用、兼容性最好的配置。


实现思路详细介绍

整体实现流程如下:

  1. 初始化 WinINet 环境

  2. 创建 Internet 会话

  3. 连接 FTP 服务器

  4. 执行文件上传 / 下载

  5. 错误处理与资源释放

项目采用函数封装方式,便于后续扩展为:

  • FTP 工具类

  • 批量上传程序

  • 自动更新模块


完整实现代码

/**************************************************** * File: FtpClient.h ****************************************************/ #pragma once #include <Windows.h> #include <WinInet.h> #include <string> #pragma comment(lib, "Wininet.lib") class FtpClient { public: FtpClient(); ~FtpClient(); bool connect(const std::wstring& server, const std::wstring& user, const std::wstring& password, INTERNET_PORT port = INTERNET_DEFAULT_FTP_PORT); bool uploadFile(const std::wstring& localFile, const std::wstring& remoteFile); bool downloadFile(const std::wstring& remoteFile, const std::wstring& localFile); private: HINTERNET hInternet; HINTERNET hFtp; }; /**************************************************** * File: FtpClient.cpp ****************************************************/ #include "FtpClient.h" #include <iostream> FtpClient::FtpClient() : hInternet(nullptr), hFtp(nullptr) { // 初始化 WinINet hInternet = InternetOpenW( L"CppFtpClient", INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr, 0 ); } FtpClient::~FtpClient() { if (hFtp) InternetCloseHandle(hFtp); if (hInternet) InternetCloseHandle(hInternet); } bool FtpClient::connect(const std::wstring& server, const std::wstring& user, const std::wstring& password, INTERNET_PORT port) { hFtp = InternetConnectW( hInternet, server.c_str(), port, user.c_str(), password.c_str(), INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0 ); return hFtp != nullptr; } bool FtpClient::uploadFile(const std::wstring& localFile, const std::wstring& remoteFile) { return FtpPutFileW( hFtp, localFile.c_str(), remoteFile.c_str(), FTP_TRANSFER_TYPE_BINARY, 0 ); } bool FtpClient::downloadFile(const std::wstring& remoteFile, const std::wstring& localFile) { return FtpGetFileW( hFtp, remoteFile.c_str(), localFile.c_str(), FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 0 ); } /**************************************************** * File: main.cpp ****************************************************/ #include "FtpClient.h" #include <iostream> int main() { FtpClient ftp; if (!ftp.connect(L"127.0.0.1", L"testuser", L"testpass")) { std::wcout << L"FTP 连接失败\n"; return 1; } if (ftp.uploadFile(L"C:\\Test\\upload.txt", L"upload.txt")) std::wcout << L"文件上传成功\n"; else std::wcout << L"文件上传失败\n"; if (ftp.downloadFile(L"download.txt", L"C:\\Test\\download.txt")) std::wcout << L"文件下载成功\n"; else std::wcout << L"文件下载失败\n"; return 0; }
/**************************************************** * File: FtpClient.h ****************************************************/ #pragma once #include <Windows.h> #include <WinInet.h> #include <string> #pragma comment(lib, "Wininet.lib") class FtpClient { public: FtpClient(); ~FtpClient(); bool connect(const std::wstring& server, const std::wstring& user, const std::wstring& password, INTERNET_PORT port = INTERNET_DEFAULT_FTP_PORT); bool uploadFile(const std::wstring& localFile, const std::wstring& remoteFile); bool downloadFile(const std::wstring& remoteFile, const std::wstring& localFile); private: HINTERNET hInternet; HINTERNET hFtp; }; /**************************************************** * File: FtpClient.cpp ****************************************************/ #include "FtpClient.h" #include <iostream> FtpClient::FtpClient() : hInternet(nullptr), hFtp(nullptr) { // 初始化 WinINet hInternet = InternetOpenW( L"CppFtpClient", INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr, 0 ); } FtpClient::~FtpClient() { if (hFtp) InternetCloseHandle(hFtp); if (hInternet) InternetCloseHandle(hInternet); } bool FtpClient::connect(const std::wstring& server, const std::wstring& user, const std::wstring& password, INTERNET_PORT port) { hFtp = InternetConnectW( hInternet, server.c_str(), port, user.c_str(), password.c_str(), INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0 ); return hFtp != nullptr; } bool FtpClient::uploadFile(const std::wstring& localFile, const std::wstring& remoteFile) { return FtpPutFileW( hFtp, localFile.c_str(), remoteFile.c_str(), FTP_TRANSFER_TYPE_BINARY, 0 ); } bool FtpClient::downloadFile(const std::wstring& remoteFile, const std::wstring& localFile) { return FtpGetFileW( hFtp, remoteFile.c_str(), localFile.c_str(), FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 0 ); } /**************************************************** * File: main.cpp ****************************************************/ #include "FtpClient.h" #include <iostream> int main() { FtpClient ftp; if (!ftp.connect(L"127.0.0.1", L"testuser", L"testpass")) { std::wcout << L"FTP 连接失败\n"; return 1; } if (ftp.uploadFile(L"C:\\Test\\upload.txt", L"upload.txt")) std::wcout << L"文件上传成功\n"; else std::wcout << L"文件上传失败\n"; if (ftp.downloadFile(L"download.txt", L"C:\\Test\\download.txt")) std::wcout << L"文件下载成功\n"; else std::wcout << L"文件下载失败\n"; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 13:17:59

OpenSpeedy终极指南:如何用开源工具掌控游戏时间流速

OpenSpeedy终极指南&#xff1a;如何用开源工具掌控游戏时间流速 【免费下载链接】OpenSpeedy 项目地址: https://gitcode.com/gh_mirrors/op/OpenSpeedy 厌倦了游戏中无聊的等待&#xff1f;想要自由调节游戏节奏&#xff1f;OpenSpeedy这款完全免费的开源游戏变速工具…

作者头像 李华
网站建设 2026/5/10 11:44:08

BBDown终极指南:5分钟掌握免费B站视频下载神器

BBDown终极指南&#xff1a;5分钟掌握免费B站视频下载神器 【免费下载链接】BBDown Bilibili Downloader. 一款命令行式哔哩哔哩下载器. 项目地址: https://gitcode.com/gh_mirrors/bb/BBDown 想要轻松保存B站视频却苦于找不到合适的工具&#xff1f;BBDown这款专业级B站…

作者头像 李华
网站建设 2026/5/15 9:12:07

小米运动步数自动同步工具2025:智能多平台数据管理完整指南

小米运动步数自动同步工具2025&#xff1a;智能多平台数据管理完整指南 【免费下载链接】mimotion 小米运动刷步数&#xff08;微信支付宝&#xff09;支持邮箱登录 项目地址: https://gitcode.com/gh_mirrors/mimo/mimotion 在当今数字化健康管理时代&#xff0c;如何高…

作者头像 李华
网站建设 2026/5/11 23:31:25

iOS个性化定制终极指南:无需越狱打造完全专属iPhone体验

iOS个性化定制终极指南&#xff1a;无需越狱打造完全专属iPhone体验 【免费下载链接】CowabungaLite iOS 15 Customization Toolbox 项目地址: https://gitcode.com/gh_mirrors/co/CowabungaLite 还在为千篇一律的iOS界面感到乏味吗&#xff1f;想要让iPhone真正成为你的…

作者头像 李华
网站建设 2026/5/9 19:30:32

ResNet18优化实战:模型量化与加速的实践

ResNet18优化实战&#xff1a;模型量化与加速的实践 1. 引言&#xff1a;通用物体识别中的ResNet-18价值 在当前AI应用广泛落地的背景下&#xff0c;轻量级图像分类模型成为边缘设备、嵌入式系统和低延迟服务的核心需求。ResNet-18作为深度残差网络中最经典的轻量版本之一&am…

作者头像 李华
网站建设 2026/5/13 15:07:32

DoL-Lyra整合包终极使用手册:5分钟快速精通秘籍

DoL-Lyra整合包终极使用手册&#xff1a;5分钟快速精通秘籍 【免费下载链接】DoL-Lyra Degrees of Lewdity 整合 项目地址: https://gitcode.com/gh_mirrors/do/DoL-Lyra 还在为Degrees of Lewdity游戏的各种Mod安装烦恼吗&#xff1f;DoL-Lyra整合包彻底改变了传统Mod管…

作者头像 李华