学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装
在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘。可是,这两天,他又抱怨他的下载程序不好用,让我们帮他写一个下载程序。
虽然我们学了C语言,虽说学了C语言,走遍天下都不怕,但是要想用C语言写一个全新的下载程序,对我们来说,就好比另外一个二万五千里长征。虽然技术上可行,但是在实际操作中却是行不通的。谁也不会傻到去用C语言写一个全新的下载程序。那么,到底怎么办呢?
如果我们看了《C程序设计伴侣》的7.A 站在巨人的肩膀上——如何使用已有的函数库这个节,要想解决这个问题,那简直就是“洒洒水啦”。在这个小节中,我们介绍了如何借助一些已有的函数库来帮助我们高质量高效率地完成一些常见任务。而其中介绍的CURL,正好是一个可以用于网络下载的开源函数库。
实际上,CURL有两种工作方式,其一,它是一个用URL语法在命令行方式下工作的文件传输工具。我们可以使用curl.exe直接在命令行下下载文件。其二,它也是一个开源的函数库,它提供了libcurl这个函数库,其中提供了多个可以用于处理网络事务(诸如下载,登陆,POST等)的API,利用这些API,我们就可以轻松地完成一个下载程序,这就好像坐上了飞机,片刻之间,就从江西瑞金到了陕北延安,一步完成二万五千里长征。
CURL的使用非常简单,跟其他类似的开源的函数库一样,其使用分为编译函数库和使用函数库两个步骤。
编译CURL函数库
在这里,我们以在Windows环境下,利用Visual C++ 2012编译为例。如果是其他环境,可以参考其文档,也很详尽。
F:\>cd code\curl-7.28.1d\winbuild
F:\code\curl-7.28.1d\winbuild>
至此,整个编译安装过程就算完成了,这样我们就可以在我们自己的程序中调用CURL所提供的API来完成文件下载的功能。这就像飞机已经加满了油,正停在跑道上等待起飞!
塔台塔台,CL2013次航班准备完毕,请求起飞。
现在,我们就可以利用其中提供的API来简便地实现一个系在程序。 /** get.c* 简易下载程序* Created on: 2013年11月1日11:13:10* Author: Bruce*/#include <curl/curl.h> #include <string.h> //用#pragam comment预编译命令,表示这个程序将使用libcurld_imp.lib这个文件 #pragma comment(lib,"libcurl.lib")//复制将数据写入文件的回调函数,关于回调函数,可以参考C程序设计伴侣8.5.4小节介绍 size_t write_data(void * ptr,size_t size,size_t nmemb,FILE * stream) {int written = fwrite(ptr,size,nmemb,stream);return written; }//使用函数库所提供函数实现文件下载函数 CURLcode download(char * url,char * out) //char * url待下载文件的URL,char * out 下载后的文件名 {CURL * curl = NULL;FILE * fp = NULL;CURLcode res;//调用函数库中的curl_easy_init()函数完成初始化curl = curl_easy_init();if(curl) //判断初始化是否成功 {//以二进制可写方式打开文件,保存下载得到的数据fp = fopen(out,"wb");//根据libcurl的使用方法,设定下载的URL,写入函数以及写入的文件 curl_easy_setopt(curl,CURLOPT_URL,url);curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data);curl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);//调用curl_easy_perform()函数执行下载操作res = curl_easy_perform(curl);//下载完成,进行最后的清理工作 curl_easy_cleanup(curl);//关闭文件 fclose(fp);return res;}else{//如果初始化失败,返回相应的错误代码return CURL_FAILED_INIT;} }//辅助函数,用于从URL中获得文件名 void getfilename(char * url,char * name) {//找到URL中的最后一个‘/’字符char* pos = strrchr(url,'/');if(NULL != pos){//将URL中文件名(从pos+1开始知道字符串结束)复制到name字符串中strcpy(name,pos+1);} }//带有参数的主函数,可以让用户在执行时,直接输入待下载文件的URL // 例如,如果我们想要下载libcurl的源代码包,则可以直接输入: // get http://curl.haxx.se/download/curl-7.24.0.zip // 关于带参数的主函数,可以参考8.7.3小节 int main(int argc,char* argv[]) {//获取用户输入的URL,判断使用方法是否正确if(2 != argc){// 提示正确的使用方法puts("usage: get http://curl.haxx.se/download/curl-7.24.0.zip");return -1;}//获取URL中的文件名char* url = argv[1];char name[32] = "";getfilename(url,name);// 调用函数库所提供函数实现的download()函数, 完成文件的下载CURLcode res = download(url,name);// 根据返回结果,提示用户下载成功与否if(CURLE_OK == res){printf("great! download %s as %s succesfully.",url,name);}else{printf("sorry:( cannot download %s.",url);}return 0; } 代码中的注释已经非常详尽了,这里就不再多加解释了。如果看完注释,还是有不明白的地方,或者想更加深入地了解这个程序, 可以参考《C程序设计伴侣》的第七章关于这个例子的介绍。 现在,我们可以用如下命令编译这个程序: cl /TP get.c 编译后,得到get.exe,也就是我们为下载狂人写的下载程序。(这里的/TP让你觉得有点不舒服? 那么看看学了C语言,如何利用cURL写一个下载程序?——在MinGW环境下实现) 下载程序的开发简单,其 使用就更简单了,比如我们要下载cURL的源代码, 可以使用下面的命令: get.exe http://curl.haxx.se/download/curl-7.28.1.zip 利用cURL,不到一百行代码,我们轻松地完成了一个下载程序,当然,如果你有兴趣,还可以进一步完善,比如加上进度提示等等。 这个事例也告诉我们一个道理: 学会站在巨人的肩膀上,可以收到事半功倍的效果 我们介绍了如何在Windows平台的Visual C++环境下利用cURL快速高效地实现一个下载程序。但是有朋友反馈说,“这是在用C++代码冒充C代码”。这位朋友说的很有道理,这是因为 Visual C++对C语言的支持并不十分完善,为了使用C语言中的一些新特性,我在编译最终代码的时候,加上了一个/TP选项,这实际上是将.c文件当作.cpp文 件来编译了,也就是把C语言代码视作了C++代码。这里需要说明的是,我们在代码中用到的全是C语言,只是在编译的时候采取了一些曲线救国的策略。虽然用/TP的方式可以解决问题,但是看起来总有些旁门左道的感觉。幸运的是,在Windows平台上,不只有Visual C++这一款编译器,还有其他的C语言编译器,比如,MInGW就是其中应用比较广泛的一款。利用MinGW,我们同样可以完成整个过程,同时还更加简 单。
- libcurl.a 静态链接库文件
- libcurldll.a 动态链接库的导入库
- libcurl.dll 动态链接库
整体来看,MinGW环境下libcurl的使用跟在Visual C++环境下的使用是相似的,只是MinGW对C语言的支持根据完善,看起来更加名门正派一些。总之,两种环境下都可以实现,而具体使用哪一种,就看你自己的喜好了。
转自:http://www.howzhi.com/course/3387/lesson/43112
转载于:https://www.cnblogs.com/kingshow123/p/easydown.html
总结
以上是生活随笔为你收集整理的学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: HTML5 Web app开发工具Ken
- 下一篇: 字符串过滤