目录
如何在windows系统下编译curl库,并在Visual studio 2019/2022下使用?
设置收到数据的回调:CURLOPT_WRITEFUNCTION
设置收到http头的回调:CURLOPT_HEADERFUNCTION
设置读取上传文件数据的回调:CURLOPT_READFUNCTION
设置上传文件的大小 CURLOPT_INFILESIZE_LARGE
设置上传文件的文件夹不存在自动创建:CURLOPT_FTP_CREATE_MISSING_DIRS
设置连接超时时间:CURLOPT_CONNECTTIMEOUT
设置等待连接时间:CURLOPT_CONNECTIONTIMEOUT
设置进度条:CURLOPT_NOPROGRESS CURLOPT_PROGRESSFUNCTION CURLOPT_PROGRESSDATA
如何在windows系统下编译curl库,并在Visual studio 2019/2022下使用?
看我之前博客:libcurl库编译并使用
利用libcurl完成传输任务的流程
-
初始化全局环境:调用
curl_global_init
。 -
创建 easy handle:调用
curl_easy_init
。 -
设置选项:使用
curl_easy_setopt
设置各种请求选项。 -
执行请求:调用
curl_easy_perform
执行请求。 -
清理 easy handle:调用
curl_easy_cleanup
释放 easy handle。 -
清理全局环境:调用
curl_global_cleanup
释放全局资源。
在整过过程中设置curl_easy_setopt()参数是最关键的,几乎所有的libcurl程序都要使用它。
常用api解析
curl_global_init()
-
函数原型:
CURLcode curl_global_init(flags)
-
作用:用于初始化 libcurl 库全局环境。在使用任何 libcurl 功能之前,必须先调用这个函数。其作用是设置 libcurl 所需的全局状态,确保库能够正常工作。
-
参数:
CURL_GLOBAL_ALL //初始化所有的可能的调用。 CURL_GLOBAL_SSL //初始化支持 安全套接字层。 CURL_GLOBAL_WIN32 //初始化win32套接字库。 CURL_GLOBAL_NOTHING //没有额外的初始化。
-
返回值:
-
返回一个
CURLcode
类型数据,如果是CURLE_OK
:表示初始化成功,其他值都是错误代码。
-
-
注意事项:
-
这个函数只能用一次(其实在调用
curl_global_cleanup
函数后仍然可再用) -
如果这个函数在
curl_easy_init
函数调用时还没调用,它将由libcurl库自动调用,所以多线程下最好主动调用该函数以防止在线程中多次使用curl_easy_init
时多次调用。 -
虽然libcurl是线程安全的,但
curl_global_init
是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init
,应该将该函数的调用放在主线程中。 -
对应的清理函数是
curl_global_cleanup
,它应该在程序结束时调用,以释放全局资源。
-
-
示例:
CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT); if (res != CURLE_OK) { std::cerr << "curl_global_init() failed: " << curl_easy_strerror(res) << std::endl; //curl_easy_strerror(res) 将错误代码转换为可读的错误消息 return 1; }
curl_global_cleanup()
-
函数原型:
void curl_global_cleanup(void)
-
作用:在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。
-
注意事项:
-
虽然libcurl是线程安全的,但
curl_global_cleanup
是不能保证线程安全的,所以不要在每个线程中都调用curl_global_cleanup
,应该将该函数的调用放在主线程中。
-
curl_easy_init()
-
函数原型:
CURL *curl_easy_init()
-
作用:用于初始化并返回一个 CURL easy handle。这个 handle 是一个用于执行 HTTP/HTTPS 请求的实例。所有的操作(如设置 URL、设置选项、执行请求等)都是通过这个 handle 完成的。
-
返回值:
-
如果成功,返回一个指向 CURL easy handle 的指针;如果失败,返回
NULL
。
-
-
注意事项:
-
在多线程中使用时,绝对不应该在线程之间共享同一个libcurl handle(CURL *对象),一个线程每次只能使用一个handle。也就是说每一个线程都得执行一次
curl_easy_init
-
curl_easy_init
用来初始化一个CURL的指针(有些像返回FILE类型的指针一样). 相应的在调用结束时要用curl_easy_cleanup
函数清理.
-
-
示例:
CURL* curl = curl_easy_init();
curl_easy_cleanup()
-
函数原型:
void curl_easy_cleanup(CURL *handle)
-
作用:这个调用用来结束一个
CURL *curl_easy_init()
创建的handle,与curl_easy_init
配合着用。 -
参数:
curl_easy_init
创建产生的CURL* curl
-
注意事项:
-
有
curl_easy_init
的地方就得有curl_easy_cleanup
。
-
curl_easy_setopt
-
函数原型:
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter...);
-
作用:用于设置
CURL *curl_easy_init()
返回的handle,这个函数是 libcurl 的核心,几乎所有的 libcurl 操作都依赖于通过curl_easy_setopt
设置选项。 -
参数:
handle:指向一个已初始化的 CURL easy handle 的指针(通过 curl_easy_init 创建)。 option:要设置的选项。(都在curl.h库里有定义,man 也可以查看到) parameter:这个参数既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量。它用什么这取决于第二个参数.
-
返回值:
如果成功,返回CURLE_OK,失败返回其他错误类型。
curl_easy_perform
-
函数原型:
CURLcode curl_easy_perform(CURL *handle);
-
作用:用于执行curl_easy_setopt设置的所有选项,curl_easy_setopt只是进行设置工作,实际的执行还是依赖于curl_easy_perform。这个函数会阻塞当前线程,直到请求完成或者发生错误。
-
参数:
handle
:指向一个已初始化并配置的 CURL easy handle 的指针(通过curl_easy_init
创建)。 -
返回值:
如果成功,返回CURLE_OK,失败返回其他错误类型。
curl_version()
-
函数原型:
char curl_version( )
-
作用:打印当前libcurl库的版本。
curl_easy_strerror()
-
函数原型:
const char *curl_easy_strerror(CURLcode)
-
作用:执行结果不为CURLE_OK是,可以用这个函数获取具体错误信息。当URL中包含空格或其他非ASCII字符时,这些字符需要被转换成相应的URL编码(也称为百分比编码)。
curl_easy_escape()
-
函数原型:
char *curl_easy_escape(CURL *handle,const char *string,int length);
-
作用:将URL中的特定字符进行编码,以确保URL在传输过程中不会因特殊字符而出现问题。
-
示例:
// 对文件名进行URL编码,否则文件名中有空格,特殊符合(#^...)会出现URL错误 std::string FtpManage::UrlEncode(const std::string &value) { CURL* curl = curl_easy_init(); if (!curl) return ""; char* output = curl_easy_escape(curl, value.c_str(), value.length()); if (output) { std::string encoded(output); curl_free(output); curl_easy_cleanup(curl); return encoded; } curl_easy_cleanup(curl); return ""; }
curl_easy_setopt函数的常用选项介绍
curl_easy_setopt
是 libcurl 库的核心函数,用于设置 CURL easy handle 的各种选项。这些选项控制请求的行为、数据处理方式、超时设置等。以下是一些常用的 curl_easy_setopt
参数和它们的作用:
设置url:CURLOPT_URL
-
说明:设置请求的 URL
-
示例:
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com");
设置get:CURLOPT_HTTPGET
-
说明:设置请求为 HTTP GET 下载模式。通常不需要显式设置,因为默认是 GET。
-
示例:
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
设置上传表单数据:CURLOPT_POST
-
说明:设置请求为 HTTP POST上传模式。
-
示例:
curl_easy_setopt(curl, CURLOPT_POST, 1L);
设置post数据:CURLOPT_POSTFIELDS
-
说明:设置 POST 请求的数据,也就是往服务器里面上传的数据是什么。使用这个参数前需要先执行
curl_easy_setopt(curl, CURLOPT_POST, 1L);
-
示例:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=John&age=30");
设置收到数据的回调:CURLOPT_WRITEFUNCTION
-
说明:需要设置回调函数,用于处理从服务器接收到的数据。
-
回调函数原型:
size_t function(void *ptr,size_t size,size_t nmemb,void *stream);
-
回函数将在libcurl接收到数据后被调用。
-
如果没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出。也可以通过 CURLOPT_WRITEDATA属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。
-
-
示例:
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) { // 处理数据 return size * nmemb; } curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
设置收到内容保存位置:CURLOPT_WRITEDATA
-
说明:这个参数用来配合CURLOPT_WRITEFUNCTION使用。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源。
-
示例:
FILE *fp = fopen("output.txt", "wb"); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
设置收到http头的回调:CURLOPT_HEADERFUNCTION
-
说明:需要设置回调函数,libcurl一旦接收到http 头部数据后将调用回调函数。
-
回调函数原型:
size_t function(void *ptr,size_t size,size_t nmemb,void *stream);
-
-
使用方式:和CURLOPT_WRITEFUNCTION相同。
CURLOPT_HEADERDATA
-
说明:这个参数用来配合CURLOPT_HEADERFUNCTION使用。CURLOPT_HEADERDATA 用于表明CURLOPT_HEADERFUNCTION函数中的stream指针的来源。
-
使用方式:和CURLOPT_WRITEDATA相同。
设置上传文件模式 CURLOPT_UPLOAD
-
说明:用于指定是否进行上传操作。设置这个选项后,libcurl 将会切换到上传模式,
CURLOPT_UPLOAD
启用后,libcurl 将会把指定的数据上传到服务器。通常需要配合其他选项(如CURLOPT_READDATA
和CURLOPT_READFUNCTION
)指定上传的数据源。值为1L
表示启用上传模式,0L
表示禁用上传模式。 -
示例:
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
设置读取上传文件数据的回调:CURLOPT_READFUNCTION
-
说明:设置读取上传数据
-
回调函数原型:
size_t function(void *ptr,size_t size,size_t nmemb,void *stream);
-
-
示例:
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
// 提供数据
return size * nmemb;
}
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
指定上传的文件:CURLOPT_READDATA
-
说明:这个参数用来配合CURLOPT_READFUNCTION使用。CURLOPT_READDATA 用于表明CURLOPT_READFUNCTION函数中的stream指针的来源。
-
使用方式:
curl_easy_setopt(curl, CURLOPT_READDATA, my_data);
设置上传文件的大小 CURLOPT_INFILESIZE_LARGE
-
说明:用于设置上传文件的大小(以字节为单位),特别适用于大文件上传。这个选项的参数是一个
curl_off_t
类型的值,用来指定将要上传的文件的大小。 -
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, ssize)
设置上传文件的文件夹不存在自动创建:CURLOPT_FTP_CREATE_MISSING_DIRS
-
说明:
CURLOPT_FTP_CREATE_MISSING_DIRS
用于在上传文件到 FTP 服务器时,如果目标目录不存在,自动创建缺失的目录。这个选项在上传文件到 FTP 服务器时非常有用,因为它可以确保路径的存在,从而避免因目录缺失导致的上传失败。 -
0L
:不创建缺失的目录(默认行为)。1L
:创建缺失的目录。 -
这个选项也可以用来创建一个文件夹。
单独创建文件夹使用方式:
curl_easy_setopt(curl, CURLOPT_URL, newpath.c_str()); curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); CURLcode res = curl_easy_perform(curl);
设置长连接:CURLOPT_TCP_KEEPALIVE
-
说明:设置设置长连接,并检测连接是否断开。通过发送周期性的 keep-alive 包,客户端和服务器可以检测连接是否已经断开,而不会依赖于应用层的数据传输。
1L
表示启用 TCP keep-alive,0L
表示禁用。 -
示例:
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
设置连接超时时间:CURLOPT_CONNECTTIMEOUT
-
说明:设置连接超时时间(秒)。
-
示例:
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L); // 5 秒连接超时
设置请求超时时间:CURLOPT_TIMEOUT
-
说明:设置请求超时时间(秒)。如果在设定的时间内请求没有完成,libcurl 将会中止请求并返回一个超时错误。这对于防止请求因网络问题或服务器响应迟缓而无限期挂起非常有用。
设置等待连接时间:CURLOPT_CONNECTIONTIMEOUT
-
说明:设置连接等待时间(秒)。用于设置 cURL 在尝试连接到服务器时等待的最大秒数。如果在这个时间之后连接还没有成功建立,cURL 将放弃尝试并返回一个错误。
设置进度条:CURLOPT_NOPROGRESS CURLOPT_PROGRESSFUNCTION CURLOPT_PROGRESSDATA
这三个选项用于控制 cURL 传输过程中的进度报告功能。
-
CURLOPT_NOPROGRESS:
-
这是一个布尔值选项,用于启用或禁用进度报告功能。
-
当设置为
true
时,cURL 将不显示任何进度信息。 -
默认情况下,cURL 会显示进度信息,所以如果你想要禁用进度报告,需要将此选项设置为
true
。
-
-
CURLOPT_PROGRESSFUNCTION:
-
这个选项允许你自定义一个回调函数,该函数将在 cURL 传输过程中被调用,以提供进度信息,默认每一秒被调用一次。
-
回调函数需要接受四个参数:资源句柄、下载的字节数、上传的字节数、总的预期字节数(如果未知则为 -1)。
-
-
CURLOPT_PROGRESSDATA:
-
这个选项用于设置传递给进度回调函数的自定义数据。
-
CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的第一个参数
-
设置重定向:CURLOPT_FOLLOWLOCATION
-
说明:用于设置cURL在遇到 HTTP 重定向(如 301 或 302 状态码)时是否自动跟随重定向到新的 URL。
-
当设置为
true
时,cURL 会自动处理 HTTP 重定向,并将请求发送到重定向后的 URL。这对于处理页面迁移或临时 URL 变化非常有用。设置为:false
则不会重定向。 -
如果设置了
CURLOPT_MAXREDIRS
,cURL 将遵循重定向,但不会超过指定的次数。
-
设置下载范围: CURLOPT_RANGE
-
说明:
CURLOPT_RANGE
用于设置 HTTP 请求的范围,允许下载文件的一部分。例如,可以使用这个选项来下载大文件的一个部分,而不是整个文件。这在处理大文件时非常有用,尤其是在需要从服务器上获取文件的特定部分时。 -
示例:
curl_easy_setopt(curl, CURLOPT_RANGE, "100-199"); //CURLOPT_RANGE 设置为 "100-199" 表示下载从字节 100 到 199 的数据。
设置断点续传:CURLOPT_RESUME_FROM
-
说明:
CURLOPT_RESUME_FROM
用于实现断点续传功能。它指定从文件的哪个字节位置开始继续下载。这个选项通常在下载中断后需要恢复下载时使用,可以避免从头开始下载整个文件。 -
示例:
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 100L); //CURLOPT_RESUME_FROM 设置为 100L 表示从字节位置 100 开始继续下载。
设置用户名和密码:CURLOPT_USERPWD
-
说明:
CURLOPT_USERPWD
用于设置用户名和密码,格式是“user:password” -
示例:
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "user_name:password");
设置私钥:CURLOPT_KEYPASSWD
-
说明:
CURLOPT_KEYPASSWD
用于设置私钥 -
示例:
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "keypassword");
设置自定义命令:CURLOPT_CUSTOMREQUEST
-
说明:用于设置自定义的 HTTP、FTP 或 SFTP 命令。该选项可以在使用一些标准方法不够灵活时帮助您发送特定的命令。
创建文件夹
创建文件夹有两种方式,一种是使用CURLOPT_CUSTOMREQUEST
自定义命令,另一种是使用CURLOPT_FTP_CREATE_MISSING_DIRS
。
-
使用
CURLOPT_CUSTOMREQUEST
自定义命令:curl_easy_setopt(curl, CURLOPT_URL, newpath.c_str()); //newpath表示包含新文件夹名称的url curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "MKD"); CURLcode res = curl_easy_perform(curl);
-
使用
CURLOPT_FTP_CREATE_MISSING_DIRS
curl_easy_setopt(curl, CURLOPT_URL, newpath.c_str()); curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); CURLcode res = curl_easy_perform(curl);
仅列出目录:CURLOPT_DIRLISTONLY
-
说明:
CURLOPT_DIRLISTONLY
是libcurl
中用于 FTP 请求的一个选项,它指定了只列出目录内容,而不包括详细的文件属性信息,当不添加CURLOPT_DIRLISTONLY选项时,默认是会将文件所有信息存储到指定位置。-
0L
:不使用DIRLISTONLY
模式,意味着默认的行为会列出目录内容,并包括详细的文件信息(如文件权限、大小、修改时间等)。 -
1L
:使用DIRLISTONLY
模式,表示仅列出目录内容,不包括文件的详细属性信息。这是最常用的设置,用于获取目录中的文件和子目录名称。
-
-
使用方式:可以使用这个选项,来列出某个FTP文件夹里面的文件列表,并且根据文件列表一个一个文件下载,实现下载整个文件夹的功能。
-
示例:
// 回调函数,用于处理Curl的响应数据 size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) { size_t totalSize = size * nmemb; output->append(static_cast<char*>(contents), totalSize);//contents里面包含的就是get请求返回的结果,这里设定为仅返回文件目录列表 return totalSize; } curl_easy_setopt(curl, CURLOPT_URL, newpath.c_str()); curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); // 仅列出目录内容 // 设置回调函数处理响应 std::string responseData; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);//文件目录会被自动写在responseData里面 CURLcode res = curl_easy_perform(curl);
使用libcurl实现FTP文件传输
包含功能为:
1、向Ftp服务器上传文件
2、从Ftp服务器下载特定文件
3、从Ftp某个文件夹里面下载所有文件
4、远程在FTP服务器指定位置创建文件夹
5、查看FTP服务器指定目录内所有文件名
解决了FTP上传/下载文件时,文件名有中文,有特殊字符时无法上传/下载的问题。
libcurl库实现FTP远程文件操作:使用libcurl库实现FTP远程文件操作(windows和linux通用)