第13章网络,Page672~674页,带进度的FTP下载的易错点及程序书写顺序

2024-01-21 08:28

本文主要是介绍第13章网络,Page672~674页,带进度的FTP下载的易错点及程序书写顺序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

网络篇,书上672~674页,带进度的FTP下载的的实例程序,写了两遍,才写成功,而且第二遍写的时候,对易错的地方有所感悟,写篇心得记下来。
首先上代码:

#include <curl/curl.h>
#include <iostream>
#include <fstream>
#include <sstream> //stringstreamusing namespace std;int to_size(char* data, size_t size, size_t nmemb, void* userdata)
{int result_code = 0;string s(data, size*nmemb);stringstream ss(s);ss >> result_code;if(!ss.bad() && result_code == 213){int* pcode = static_cast <int*> (userdata);ss >> *pcode;}return nmemb*size;
}int to_stream(char* data, size_t size, size_t nmemb, void* userdata)
{ostream& os = *static_cast <ostream*> (userdata);std::string line(data, size*nmemb);os << line;return size*nmemb;
}//当需要通知进度时,回调
int down_progress(void*, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{if(dltotal == 0)return 0;int count = (dlnow * 1.0 / dltotal) * 50; //确定需要画多少个等号cout << (dlnow * 100 / dltotal) << "%"; //确定百分比for(int i = 0; i < count; ++i){cout << '=';}cout << endl;return 0;
}//取FTP服务器指定文件的大小
int get_server_file_size(string const& server_url, string const& username, string const& password, string const& pathfile)
{CURL* handle = curl_easy_init();curl_easy_setopt(handle, CURLOPT_URL, server_url.c_str());//username和password也需要C形式的字符串curl_easy_setopt(handle, CURLOPT_USERNAME, username.c_str());curl_easy_setopt(handle, CURLOPT_PASSWORD, password.c_str());string cmd = "SIZE " + pathfile; //SIZE后面要有个分号curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, cmd.c_str());int filesize = 0;curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, to_size);curl_easy_setopt(handle, CURLOPT_HEADERDATA, static_cast <void*> (&filesize));curl_easy_perform(handle);cout << "filesize = " << filesize << endl;curl_easy_cleanup(handle);return filesize;
}int main()
{curl_global_init(CURL_GLOBAL_DEFAULT);CURL* handle = curl_easy_init();ofstream ofs("a.zip", ios_base::out | ios_base::binary);if(!ofs){cerr << "无法打开本地文件a.zip。" << endl;return -1;}string server_url = "ftp://127.0.0.1:21/";string pathfile = "fengjie/meili/2.zip";string username = "d2school";string password = "123456";//取服务端指定文件大小size_t file_size = get_server_file_size(server_url, username, password, pathfile);//告诉libcurl待下载文件的总大小curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, static_cast <curl_off_t> (file_size));//开启进度通知curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);curl_easy_setopt(handle, CURLOPT_XFERINFOFUNCTION, down_progress);//设置如何处理下载的数据string url = server_url + pathfile;curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
//    //username和password也需要C形式的字符串curl_easy_setopt(handle, CURLOPT_USERNAME, username.c_str());curl_easy_setopt(handle, CURLOPT_PASSWORD, password.c_str());//本次下载采用直接定位到文件的方式,类似于http协议的下载,不需要使用ftp命令: RETR 文件名curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, to_stream);curl_easy_setopt(handle, CURLOPT_WRITEDATA, static_cast <void*> (&ofs));curl_easy_perform(handle);//启动下载ofs.close();//关闭流curl_easy_cleanup(handle);curl_global_cleanup();return 0;
}


易错点分析:

65行,要注意SIZE后面要有个分号
62,63, 107,108行,要注意username和password不要忘了使用c_str()转化成“C”形式的字符串
110行,本次下载采用直接定位到文件的方式,类似于http协议的下载,不需要使用ftp命令: RETR 文件名
116行,关闭流,这个容易遗忘。不过这一行即使遗忘了,应该也不会有问题,因为ofs是栈变量,会自动回收内存。
写的过程要注意:不要一口气把整个程序写完,否则出了错,会花费老大劲去寻找错误。
首先,main函数中,写到96行,要测试一下,看看能不能得到文件的大小,如果不能得到,则停下来,排查错误。把错误解决完,再继续往下写。

接下来,先写104-112行的内容,看看能否把文件下载下来,若不能,则同样排查错误。把错误解决完,再继续写98-101行的内容,把下载进度通知加上。

这篇关于第13章网络,Page672~674页,带进度的FTP下载的易错点及程序书写顺序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/628923

相关文章

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

SQL server数据库如何下载和安装

《SQLserver数据库如何下载和安装》本文指导如何下载安装SQLServer2022评估版及SSMS工具,涵盖安装配置、连接字符串设置、C#连接数据库方法和安全注意事项,如混合验证、参数化查... 目录第一步:打开官网下载对应文件第二步:程序安装配置第三部:安装工具SQL Server Manageme

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置