您的位置:首页 > 理论基础 > 计算机网络

使用libcurl库进行HTTP的下载

2010-06-03 14:29 369 查看
由于这段时间需要进行跨平台的代码处理,以前写的很多代码都没办法用了.以前用的是win的WinInet库进行HTTP上传和下载的,在Linux下肯定无法使用了,而我又对socket这些东西不是很了解,只能找一些第三方的跨平台库来使用了.不知道出于啥原因,选择了libcurl.然后花了数天时间来了解这个库有关上传下载的东西,可能我的搜索水平有限吧,直到这两天才真正找到一些可供参考的东西.当然我也试着阅读了libcurl的官方文档,但很无奈,英文水平太差,读完后还是不知道该怎么用.

先贴三个对此次学习帮助最大的三个网址吧:

curl官网:http://curl.haxx.se/libcurl/

JGood对libcurl很多函数的官方文档翻译,加了一些实例,很清晰: http://blog.csdn.net/JGood/archive/2009/11/08/4787670.aspx

浪迹天涯对libcurl的一些使用心得,从中我得到了怎么判断HTTP地址的文件是否存在的判断方法:

http://www.cppblog.com/qiujian5628/archive/2008/06/28/54873.html

先说下思路吧:

用curl库,一般步骤为:

先使用curl_global_init()初始化curl,然后使用curl_easy_init()获取curl句柄,再根据得到的句柄进行一些操作设置curl_easy_setopt(),设置完后用curl_easy_peform()执行你以前所做的所有设置.若在设置上做了READ或WRITE等动作,在执行完后还可以用curl_easy_getinfo()来获取你取得的一些东西,这里可以进行一些判断(我就是在这里判断HTTP头,来处理到底远程文件是否存在的).最后就是用curl_easy_cleanup(),curl_global_cleanup()来清理以前初始化的东西.

具体的请看JGod大大的blog.

比较需要了解的还是curl_easy_setopt()的参数:

curl_easy_setopt(curl, CURLOPT_URL, "http://****");   //获取url地址
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_fun);   //重载一个写文件的回调函数(默认的只是简单的把数据流输出到屏幕)
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);   //给回调函数传递一个自定义参数data(出现在第4个参数)
curl_easy_setopt(curl, CURLOPT_READFUNCTION, &read_fun);
curl_easy_setopt(curl, CURLOPT_READDATA, &read_fun);    //参见WRITE


设置好后就能利用curl进行文件的上传和下载了.

接下来进入主题,上代码:

//WRITEFUNCTION回调函数的实现,在这里只做简单的处理
size_t process_data(void *buffer, size_t size, size_t nmemb, std::string& user_p)
{
user_p = (char*)buffer;

return nmemb;
}

const int FILE_EXIST = 200;

int down_file(const char* url, const char* down_file_name)
{
// 初始化libcurl
CURLcode return_code;
return_code = curl_global_init(CURL_GLOBAL_ALL);
if (CURLE_OK != return_code)
{
cerr << "init libcurl failed." << endl;
curl_global_cleanup();
return -1;
}

// 获取easy handle
CURL *easy_handle = curl_easy_init();
if (NULL == easy_handle)
{
cerr << "get a easy handle failed." << endl;
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
return -1;
}

// 设置easy handle属性
return_code = curl_easy_setopt(easy_handle, CURLOPT_URL, url);

//设置回调函数
return_code = curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, &process_data);

//回调函数的额外参数
std::string connectx;
return_code = curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &connectx);

// 执行数据请求
return_code = curl_easy_perform(easy_handle);

//判断获取响应的http地址是否存在,若存在则返回200,400以上则为不存在,一般不存在为404错误
int retcode = 0;
return_code = curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE , &retcode);
if (CURLE_OK == return_code && FILE_EXIST == retcode)
{
double length = 0;
return_code = curl_easy_getinfo(easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD , &length);
FILE *fp = fopen(save_name.c_str(), "wb+");
fwrite(connectx.c_str(), 1, length, fp);	//返回实际写入文本的长度,若不等于length则写文件发生错误.
fclose(fp);
}
else
{
std::cout << "请求的文件不存在!" << std::endl;
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
return -1;
}

// 释放资源
curl_easy_cleanup(easy_handle);
curl_global_cleanup();

return 0;
}


在外部只要传入url如:http://192.168.1.1/868.txt,和欲存到本地的文件名file_name就行了.

忘了说明了,这目前只是在win下知道怎么用了,linux下还没有编译,等把上传实现了再说.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: