curl使用小结
最近在学习curl,顺便记录一下:
常用函数简要说明
- curl_easy_init()
初始化一个licurl简单会话,这个API应该最先调用,它会返回一个handle,供其他API使用。 - curl_easy_cleanup()
清除CURL指针,如果前面调用了curl_easy_init(),后面就一定要调用curl_easy_cleanup(),相当于释放资源。 - curl_easy_setopt()
给curl的easy handle设置一个传输选项,这是一个很重要的函数,也是用的最多的一个,如果你要对curl进行什么操作,大多需要透过这个API去设定。 - curl_easy_perform()
执行传输任务 - curl_easy_getinfo()
从curl handle提取相应的信息
curl_easy_setopt常用设置说明
- CURLOPT_URL
设定要访问的URL - CURLOPT_VERBOSE
打开一些传输过程的信息,常用于调试时,查看信息 - CURLOPT_FOLLOWLOCATION
打开重定向跟踪 - CURLOPT_WRITEFUNCTION、CURLOPT_WRITEDATA
CURLOPT_WRITEFUNCTION:设置一个回调函数,用于保存接收到的数据
回调函数:size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
ptr:指向接收到的数据
userdata:CURLOPT_WRITEDATA设置的参数
写入数据的大小为size*nmemb
CURLOPT_WRITEDATA:用于设定上面回调函数的最后一个参数 - CURLOPT_HEADERFUNCTION、CURLOPT_HEADERDATA
上面两个选项主要用于保存header data,使用方法可以参考CURLOPT_WRITEFUNCTION和CURLOPT_WRITEDATA - CURLOPT_NOPROGRESS、CURLOPT_PROGRESSFUNCTION、CURLOPT_PROGRESSDATA
这三个选项主要用来得到当前任务的传输进度,具体用法可以参考下面的例子
curl_easy_getinfo常用设置说明
- CURLINFO_REDIRECT_URL
获取重定向的URL - CURLINFO_CONTENT_TYPE
获取传输的数据类型 - CURLINFO_SIZE_DOWNLOAD
下载文件的大小 - CURLINFO_TOTAL_TIME
下载文件所花的总时间 - CURLINFO_SPEED_DOWNLOAD
下载文件的平均速度
例程
- http post
INT32 libcurl_http_post(const CHAR * url, const CHAR * postFields)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields);
res = curl_easy_perform(curl);
if(CURLE_OK != res)
{
curl_easy_cleanup(curl);
return LIBCURL_RET_FAIL;
}
curl_easy_cleanup(curl);
}
return LIBCURL_RET_OK;
}
- 获取重定向URL
INT32 libcurl_get_redirect_url(const CHAR * url)
{
char *redirectUrl;
CURLcode res;
res = curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
if(curl)
{
char *version = curl_version();
printf("CURL version is %s
", version);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
if(CURLE_OK == res)
{
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &redirectUrl);
printf("Redirect URL is : %s
", redirectUrl);
}
curl_easy_cleanup(curl);
curl_global_cleanup();
}
return LIBCURL_RET_OK;
}
- 获取http头
static size_t libcurl_http_get_header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE *fp = (FILE *)stream;
return fwrite(ptr, size, nmemb, fp);
}
INT32 libcurl_http_get_header(const CHAR * url, const CHAR * pageSavePath)
{
CURL *curl;
CURLcode res;
FILE *fp;
res = curl_global_init(CURL_GLOBAL_ALL);
if(CURLE_OK != res)
{
return LIBCURL_RET_FAIL;
}
curl = curl_easy_init();
if(curl)
{
if(NULL == (fp = fopen(pageSavePath, "w+")))
{
printf("Open file error
");
return LIBCURL_RET_FAIL;
}
curl_easy_setopt(curl, CURLOPT_URL, url);
//curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, libcurl_http_get_header_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp);
res = curl_easy_perform(curl);
if(CURLE_OK != res)
{
curl_easy_cleanup(curl);
return LIBCURL_RET_FAIL;
}
curl_easy_cleanup(curl);
}
return LIBCURL_RET_OK;
}
- 保存一个网页
static size_t libcurl_http_get_page_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE *fp = (FILE *)stream;
size_t return_size = fwrite(ptr, size, nmemb, fp);
return return_size;
}
INT32 libcurl_http_get_page(const char * url, const char *pageSavePath)
{
CURL *curl;
CURLcode res;
FILE *fp = NULL;
if(NULL == (fp =fopen(pageSavePath, "wb")))
{
printf("open fail
");
fclose(fp);
return LIBCURL_RET_FAIL;
}
res = curl_global_init(CURL_GLOBAL_ALL);
if(CURLE_OK != res)
{
return LIBCURL_RET_FAIL;
}
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, libcurl_http_get_page_callback);
curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)fp);
res = curl_easy_perform(curl);
if(CURLE_OK == res)
{
char *contentType;
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType);
if((CURLE_OK == res) && contentType)
printf("We received Content-Type: %s
", contentType);
}
curl_easy_cleanup(curl);
}
fclose(fp);
return LIBCURL_RET_OK;
}
- 下载一个文件并显示下载进度
static size_t libcurl_file_download_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE *fp = (FILE *)stream;
return fwrite(ptr, size, nmemb, fp);
}
static INT32 libcurl_file_download_progress_callback(void *p,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
int currentPercent = 0;
if(t != 0)
{
currentPercent = (int)((double)100*(d/t));
}
printf("download percent : %d
", currentPercent);
return LIBCURL_RET_OK;
}
INT32 libcurl_file_download(const CHAR *url, const CHAR * fileSavePath)
{
CURL *curl;
CURLcode res;
FILE *fp;
res = curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl)
{
if(NULL == (fp = fopen(fileSavePath, "w+")))
{
printf("Open file error
");
return LIBCURL_RET_FAIL;
}
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, libcurl_file_download_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, libcurl_file_download_progress_callback);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,curl);
//curl_easy_setopt(curl, CURLOPT_RANGE,"0-300000");
//curl_easy_setopt(curl, CURLOPT_RANGE,"300001-600000");
//curl_easy_setopt(curl, CURLOPT_RANGE,"600001-900000");
//curl_easy_setopt(curl, CURLOPT_RANGE,"0-500000");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // display debug msg
res = curl_easy_perform(curl);
if(CURLE_OK == res)
{
double val;
char *contentType;
res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &val);
if((CURLE_OK == res) && (val>0))
printf("Data downloaded: %0.0f bytes.
", val);
res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &val);
if((CURLE_OK == res) && (val>0))
printf("Total download time: %0.3f sec.
", val);
res = curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, &val);
if((CURLE_OK == res) && (val>0))
printf("Average download speed: %0.3f kbyte/sec.
", val / 1024);
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType);
if((CURLE_OK == res) && contentType)
printf("Content-Type: %s
", contentType);
}
if(fp)
fclose(fp);
curl_easy_cleanup(curl);
}
return LIBCURL_RET_OK;
}
- ftp 上传
INT32 libcurl_ftp_upload_file(const CHAR * ftpAddress, const CHAR * localFilePath, const CHAR * userPwd)
{
CURL *curl;
CURLcode res;
struct stat file_info;
curl_off_t fsize;
if(stat(localFilePath, &file_info))
{
printf("Can not open %s
", localFilePath);
return LIBCURL_RET_FAIL;
}
fsize = (curl_off_t)file_info.st_size;
FILE *fp = fopen(localFilePath, "rb");
res = curl_global_init(CURL_GLOBAL_ALL);
if(CURLE_OK != res)
{
return LIBCURL_RET_FAIL;
}
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_USERPWD, userPwd);
curl_easy_setopt(curl, CURLOPT_URL, ftpAddress);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
//curl_easy_setopt(curl, CURLOPT_PUT, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, fp);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize);
res = curl_easy_perform(curl);
if(CURLE_OK != res)
{
curl_easy_cleanup(curl);
return LIBCURL_RET_FAIL;
}
if(fp)
fclose(fp);
curl_easy_cleanup(curl);
curl_global_cleanup();
}
return LIBCURL_RET_OK;
}
- ftp 下载
static size_t libcurl_ftp_download_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE *fp = (FILE *)stream;
return fwrite(ptr, size, nmemb, fp);
}
INT32 libcurl_ftp_download_file(const CHAR * ftpAddress, const CHAR * userPwd, const CHAR * fileSavePath)
{
CURL *curl;
CURLcode res;
FILE *fp = fopen(fileSavePath, "w+");
if(NULL == fp)
{
printf("Open file error
");
return LIBCURL_RET_FAIL;
}
res = curl_global_init(CURL_GLOBAL_ALL);
if(CURLE_OK != res)
{
return LIBCURL_RET_FAIL;
}
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_USERPWD, userPwd);
curl_easy_setopt(curl, CURLOPT_URL, ftpAddress);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, libcurl_ftp_download_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
if(CURLE_OK != res)
{
curl_easy_cleanup(curl);
return LIBCURL_RET_FAIL;
}
if(fp)
fclose(fp);
curl_easy_cleanup(curl);
curl_global_cleanup();
}
return LIBCURL_RET_OK;
}
- 保存下载内容到buffer中
struct MemoryStruct {
CHAR *memory;
size_t size;
};
struct MemoryStruct chunk;
static size_t curl_http_write_memory_cb(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if (mem->memory == NULL) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)
");
exit(EXIT_FAILURE);
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
INT32 curl_http_get_page(const CHAR * url)
{
CURL *curl;
CURLcode res;
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
res = curl_global_init(CURL_GLOBAL_ALL);
if(CURLE_OK != res)
{
return CURL_RET_FAIL;
}
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curl_http_write_memory_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
return CURL_RET_OK;
}
参考资料
- 百度百科libcurl
- libcurl官网
- curl_easy_setopt说明文档
- curl_easy_getinfo说明文档
- 最全的libcurl库资源整理
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。