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

这篇具有很好参考价值的文章主要介绍了第13章网络,Page672~674页,带进度的FTP下载的易错点及程序书写顺序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

#include <curl/curl.h>
#include <iostream>
#include <fstream>
#include <sstream> //stringstream

using 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行的内容,把下载进度通知加上。文章来源地址https://www.toymoban.com/news/detail-820481.html

到了这里,关于第13章网络,Page672~674页,带进度的FTP下载的易错点及程序书写顺序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第13章 网络 Page738~741 13.8.3 TCP/UDP简述

    libcurl是C语言写成的网络编程工具库,asio是C++写的网络编程的基础类型库 libcurl只用于客户端,asio既可以写客户端,也可以写服务端 libcurl实现了HTTPFTP等应用层协议,但asio却只实现了传输层TCP/UDP等协议。 在学习http时介绍过“OSI网络七层”协议,但实际应用更多的是“TCP/

    2024年02月20日
    浏览(31)
  • torch.nn.functional.grid_sample(F.grid_sample)函数的说明 & 3D空间中的点向图像投影的易错点

    由于二者有一定共通之处,因此放在一篇文章内介绍。   该函数的作用是在图像/体素空间中采样特征。 变量名 数据类型 默认值 含义 备注 input Tensor - 原始图像/体素空间的特征 形状需为 ( B , C , H , W ) (B,C,H,W) ( B , C , H , W ) 或 ( B , C , D , H , W ) (B,C,D,H,W) ( B , C , D , H , W ) ,分

    2023年04月24日
    浏览(46)
  • 第13章 网络 Page818 UDP(和TCP的比较)

    TCP核心类 UPD核心类 UPD中没有acceptor(接收器)。 另外:address类,归属在ip下面,这意味着它即可用于TCP,又可用于UDP UDP协议也称为“无连接协议”,即通信之前不需要事先建立连接。 但逻辑上仍然可以区分出“客户端”和“服务端”,主动的那一端就是客户端。客户端也仍然

    2024年02月20日
    浏览(39)
  • 第13章 网络 Page741~744 asio核心类 ip::tcp::socket

    liburl库使用\\\"curl*\\\" 代表socket 句柄 asio库使用ip::tcp::socket类代表TCP协议下的socket对象。 将“句柄”换成“对象”,因为asio库是不打折扣的C++库 ip::tcp::socket提供一下常用异步操作都以async开头 表13-3 tcp::socket提供的异步操作 async_connect() Start an asynchronous connect async_read_some() Start an

    2024年02月20日
    浏览(31)
  • 第13章 网络 Page747~749 asio核心类 ip::tcp::resolver

    如果新浪的IP地址变了,该怎么办呢? ip::tcp::resolver 可以帮我们用上www.sina.com.cn,因为它负责将人类可读的多种网址信息,一步 到位地解析成ip::tcp::socket建立连接所需要的ip::tcp::endpoint结构,address类被直接跳过。 实际操作分三步 第一步 准备解析条件。 条件是一个类型 ip::t

    2024年02月19日
    浏览(41)
  • 【Linux命令详解 | wget命令】 wget命令用于从网络下载文件,支持HTTP、HTTPS和FTP协议

    在编程世界中,处理网络资源是一项关键任务,而 wget 命令就是一位可靠的助手。 wget (全名为“Web Get”)是一种用于从网络下载文件的工具,它能够处理多种协议,包括HTTP、HTTPS和FTP。作为一个博主,我们可以利用 wget 命令来获取文件、备份网站内容、自动下载资源等。

    2024年02月12日
    浏览(38)
  • 13.8.1异步、异步、异步 Page720~721

    运行效果: 开始运行: 5秒后: 再过5秒:

    2024年01月23日
    浏览(28)
  • 【软考复习系列】计算机网络易错知识点记录

    参考文章:图解路由器:这玩意儿能连接全世界的网络? - 知乎 (zhihu.com) 宏内核和微内核 宏内核应该叫单内核或者单核。在这种单核的设计中,内核是一个大的整体,所有内核服务都运行在一个地址空间中,函数之间的调用链路少,直接通信简单高效。 微内核的功能会划分

    2024年02月08日
    浏览(37)
  • 命令行下载FTP文件

    目录  介绍本次用到的 DOS 命令 1. 打开命令行 2. 进入 FTP 3. 连接 FTP 4. 输入用户名及密码 5. 查看 FTP 文件目录 6. 进入【HIS】文件夹 7. 指定本地文件夹 8. 开关交互模式 9. 下载文件 10. 下载时会有提示 11. 耗时计算         本文旨在说明如何以命令行的方式直接下载 FTP 上的

    2023年04月17日
    浏览(28)
  • 通过FTP下载数据

    FTP全称File Transfer Protocol, 中文名为“文件传输协议”。遇到需要下载的数据非常大的时候,常通过FTP来进行文件下载。步骤如下: (1)安装FileZilla软件,这是软件下载的网址https://www.filezilla.cn/download/client 我选了绿色版,免安装。 (2)打开FileZilla软件,初始界面如下,只有

    2024年02月11日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包