版权声明:所有版权归作者她的吻让他,转载请标明出处. https://blog.csdn.net/qq_37059136/article/details/83856013
前言
由于某些需求,可能要求在下载时使用ftp主动模式下载,关于ftp的主、被动模式这里我就不多做解释,有兴趣的可以自己百度
相关知识
这篇博文基于libcurl库实战之下载ftp文件并实时显示百分比,当然了,基本后续的所有功能添加都会基于该博文,关于ftp下载的相关知识可以在链接博文中找到
ftp主动模式下载:
该功能在libcurl下也不过是一个参数设置而已
//设置主动模式
curl_easy_setopt(curl,CURLOPT_FTPPORT,"192.168.6.174:100000-110000");
curl_easy_setopt(curl,CURLOPT_FTPPORT,"192.168.6.174:0");
这两句都是设置主动模式的语句,区别就是上面那句设定了具体的主动端口区间,在连接时只能选择100000-110000区间的空闲端口号,关于这里端口号区间的选择,本人理解是能大就大,ftp的本身占用20,21两个端口(默认情况下),21端口可以修改,因此你的端口区间可能被用作其他ftp的端口号,所以这个区间能大就大,当然了,如果没有特殊需求,可以使用下面的语句进行主动模式设置
下面这句设置的0是什么意思呢?意思就是主动模式下,任意挑选本地空闲的端口号来进行数据传送,这个是不是很方便呢,哈哈哈
代码
#include <string>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "curl.h"
#include <stdio.h>
using namespace std;
#pragma comment(lib,"libcurl.lib")
struct FtpFile
{
const char *filename;
FILE *stream;
};
static size_t FetchFiles(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out = (struct FtpFile *)stream;
if (out && !out->stream)
{
// open file for writing
out->stream = fopen(out->filename, "wb");
if (!out->stream)
return -1; // failure, can't open file to write
}
return fwrite(buffer, size, nmemb, out->stream);
}
int my_progress_func(char *progress_data,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
printf("%s %g / %g (%g %%)\n", progress_data, d, t, d*100.0/t);
return 0;
}
int DownloadFtpFile()
{
CURL *curl;
CURLcode res;
char *progress_data = "* ";
struct FtpFile ftpfile = {
"E:\\vs文档\\1031CURL_TEST\\FtpDownLoad\\UltraEdit-32.rar", // name to store the file as if succesful//
NULL
};
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL,"ftp://ljl:[email protected]:21/UltraEdit-32(UE)/UltraEdit-32.rar");
curl_easy_setopt(curl, CURLOPT_USERPWD, "ljl:521125");
//设置主动模式
//curl_easy_setopt(curl,CURLOPT_FTPPORT,"192.168.6.174:100000-110000");
curl_easy_setopt(curl,CURLOPT_FTPPORT,"192.168.6.174:0");
// Define our callback to get called when there's data to be written //
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, FetchFiles);
// Set a pointer to our struct to pass to the callback //
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress_data);
// Switch on full protocol/debug output //
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
// always cleanup
curl_easy_cleanup(curl);
if (CURLE_OK != res)
{
//we failed
fprintf(stderr, "curl told us %d\n", res);
}
}
if (ftpfile.stream)
fclose(ftpfile.stream); // close the local file
curl_global_cleanup();
getchar();
return 0;
}
int main(void)
{
DownloadFtpFile();
return 0;
}
后续
该片博文的代码承袭链接的博文,有不清楚的可以去链接博文查看