使用libcurl的正确姿势

使用libcurl的正确姿势

来源:互联网     时间:2015-8-10 12:45:41
id="iframeu2324488_0" src="http://pos.baidu.com/acom?rdid=2324488&dc=2&di=u2324488&dri=0&dis=0&dai=7&ps=404x531&dcb=BAIDU_EXP_UNION_define&dtm=BAIDU_DUP_SETJSONADSLOT&dvi=0.0&dci=-1&dpt=none&tsr=326&tpr=1452650930581&ti=%E4%BD%BF%E7%94%A8libcurl%E7%9A%84%E6%AD%A3%E7%A1%AE%E5%A7%BF%E5%8A%BF_C%2FC%2B%2B%E6%95%99%E7%A8%8B_%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B_%E7%A0%81%E8%9A%81%E4%B9%8B%E5%AE%B6_www.codes51.com&ari=1&dbv=2&drs=1&pcs=1406x823&pss=1406x1784&cfv=18&cpl=6&chi=1&cce=true&cec=UTF-8&tlm=1452650930&ltu=http%3A%2F%2Fwww.codes51.com%2Farticle%2Fdetail_159678.html&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DG5t91UE0tQAwXbSQa1fZll0LjvIb35MkCPXj3z2CtjAUGA-qI-1vRM-srTv72yJ6BIDzEuQXyzLb0vGrDAGF2K%26wd%3D%26eqid%3D856688b8001102cc000000035695b18e&ecd=1&psr=1920x1080&par=1920x1019&pis=-1x-1&ccd=24&cja=true&cmi=8&col=en-US&cdo=-1&tcn=1452650931&exps=110211&qn=5ad762e9cb9b6d2b&tt=1452650930540.329.391.392&feid=110211" width="550" height="22" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="border-width: 0px; border-style: initial; vertical-align: bottom; margin: 0px;">

本篇文章主要介绍了"使用libcurl的正确姿势",主要涉及到方面的内容,对于C/C++教程感兴趣的同学可以参考一下: libcurl支持访问http、ftp等各种服务器,下载图片AV什么的不在话下。但其存在多种接口,异步接口也很难以理解,到底什么样的使用姿势才是正确滴?我们来看...

  • id="iframeu2029198_0" src="http://pos.baidu.com/acom?rdid=2029198&dc=2&di=u2029198&dri=0&dis=0&dai=8&ps=570x539&dcb=BAIDU_EXP_UNION_define&dtm=BAIDU_DUP_SETJSONADSLOT&dvi=0.0&dci=-1&dpt=none&tsr=376&tpr=1452650930581&ti=%E4%BD%BF%E7%94%A8libcurl%E7%9A%84%E6%AD%A3%E7%A1%AE%E5%A7%BF%E5%8A%BF_C%2FC%2B%2B%E6%95%99%E7%A8%8B_%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B_%E7%A0%81%E8%9A%81%E4%B9%8B%E5%AE%B6_www.codes51.com&ari=1&dbv=2&drs=1&pcs=1406x823&pss=1406x2034&cfv=18&cpl=6&chi=1&cce=true&cec=UTF-8&tlm=1452650930&ltu=http%3A%2F%2Fwww.codes51.com%2Farticle%2Fdetail_159678.html&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DG5t91UE0tQAwXbSQa1fZll0LjvIb35MkCPXj3z2CtjAUGA-qI-1vRM-srTv72yJ6BIDzEuQXyzLb0vGrDAGF2K%26wd%3D%26eqid%3D856688b8001102cc000000035695b18e&ecd=1&psr=1920x1080&par=1920x1019&pis=-1x-1&ccd=24&cja=true&cmi=8&col=en-US&cdo=-1&tcn=1452650931&exps=110211&qn=83b7415a7a80bbe3&tt=1452650930540.379.661.662&feid=110211" width="300" height="250" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="border-width: 0px; border-style: initial; vertical-align: bottom; margin: 0px;">
  • id="iframeu1771497_0" src="http://pos.baidu.com/acom?rdid=1771497&dc=2&di=u1771497&dri=0&dis=0&dai=9&ps=592x539&dcb=BAIDU_EXP_UNION_define&dtm=BAIDU_DUP_SETJSONADSLOT&dvi=0.0&dci=-1&dpt=none&tsr=409&tpr=1452650930581&ti=%E4%BD%BF%E7%94%A8libcurl%E7%9A%84%E6%AD%A3%E7%A1%AE%E5%A7%BF%E5%8A%BF_C%2FC%2B%2B%E6%95%99%E7%A8%8B_%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B_%E7%A0%81%E8%9A%81%E4%B9%8B%E5%AE%B6_www.codes51.com&ari=1&dbv=2&drs=1&pcs=1406x823&pss=1406x2034&cfv=18&cpl=6&chi=1&cce=true&cec=UTF-8&tlm=1452650930&ltu=http%3A%2F%2Fwww.codes51.com%2Farticle%2Fdetail_159678.html&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DG5t91UE0tQAwXbSQa1fZll0LjvIb35MkCPXj3z2CtjAUGA-qI-1vRM-srTv72yJ6BIDzEuQXyzLb0vGrDAGF2K%26wd%3D%26eqid%3D856688b8001102cc000000035695b18e&ecd=1&psr=1920x1080&par=1920x1019&pis=-1x-1&ccd=24&cja=true&cmi=8&col=en-US&cdo=-1&tcn=1452650931&exps=110211&qn=0caca6e611dbca20&tt=1452650930540.411.671.671&feid=110211" width="300" height="250" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="border-width: 0px; border-style: initial; vertical-align: bottom; margin: 0px;">

libcurl支持访问http、ftp等各种服务器,下载图片AV什么的不在话下。但其存在多种接口,异步接口也很难以理解,到底什么样的使用姿势才是正确滴?我们来看看可用的体位:

  • easy interface:最简单的同步接口,容易理解,但同步访问实在不是性能之选。至于引入多线程,那是简单问题复杂化。注意异步访问也是以easy interface为基础,所以还是要学习一下:《libcurl教程》。
  • multi interface:异步访问接口,性能杠杠滴,但是。。。真的很难理解啊。。。官方文档:《multi interface overview》。

    • curl_multi_perform() + select():select()性能不够好,还受到file descriptors不能大于1024的限制。参考《使用libcurl进行异步并发访问与文件上传》。
    • curl_multi_socket_action():使用epoll模型,性能最好,但更难懂。。。参考范例。
    • curl_multi_perform() + curl_multi_wait():这个据说是facebook做出的伟大贡献(参见《Introducing curl_multi_wait》),保证性能的同时也相对容易使用,强力推荐的姿势。抄录示例代码如下:

      /* curl_multi_test.c
         Clemens Gruber, 2013
         <clemens.gruber@pqgruber.com>
         Code description:
          Requests 4 Web pages via the CURL multi interface
          and checks if the HTTP status code is 200.
         Update: Fixed! The check for !numfds was the problem.
      */
      
      #include <stdio.h>
      #include <stdlib.h>
      #ifndef WIN32
      #include <unistd.h>
      #endif
      #include <curl/multi.h>
      
      #define MAX_WAIT_MSECS 30*1000 /* Wait max. 30 seconds */
      
      static const char *urls[] = {
        "http://www.microsoft.com",
        "http://www.yahoo.com",
        "http://www.wikipedia.org",
        "http://slashdot.org"
      };
      #define CNT 4
      
      static size_t cb(char *d, size_t n, size_t l, void *p)
      {
        /* take care of the data here, ignored in this example */
        (void)d;
        (void)p;
        return n*l;
      }
      
      static void init(CURLM *cm, int i)
      {
        CURL *eh = curl_easy_init();
        curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
        curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
        curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
        curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
        curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
        curl_multi_add_handle(cm, eh);
      }
      
      int main(void)
      {
          CURLM *cm=NULL;
          CURL *eh=NULL;
          CURLMsg *msg=NULL;
          CURLcode return_code=0;
          int still_running=0, i=0, msgs_left=0;
          int http_status_code;
          const char *szUrl;
      
          curl_global_init(CURL_GLOBAL_ALL);
      
          cm = curl_multi_init();
      
          for (i = 0; i < CNT; ++i) {
              init(cm, i);
          }
      
          curl_multi_perform(cm, &still_running);
      
          do {
              int numfds=0;
              int res = curl_multi_wait(cm, NULL, 0, MAX_WAIT_MSECS, &numfds);
              if(res != CURLM_OK) {
                  fprintf(stderr, "error: curl_multi_wait() returned %d\n", res);
                  return EXIT_FAILURE;
              }
              /*
               if(!numfds) {
                  fprintf(stderr, "error: curl_multi_wait() numfds=%d\n", numfds);
                  return EXIT_FAILURE;
               }
              */
              curl_multi_perform(cm, &still_running);
      
          } while(still_running);
      
          while ((msg = curl_multi_info_read(cm, &msgs_left))) {
              if (msg->msg == CURLMSG_DONE) {
                  eh = msg->easy_handle;
      
                  return_code = msg->data.result;
                  if(return_code!=CURLE_OK) {
                      fprintf(stderr, "CURL error code: %d\n", msg->data.result);
                      continue;
                  }
      
                  // Get HTTP status code
                  http_status_code=0;
                  szUrl = NULL;
      
                  curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, &http_status_code);
                  curl_easy_getinfo(eh, CURLINFO_PRIVATE, &szUrl);
      
                  if(http_status_code==200) {
                      printf("200 OK for %s\n", szUrl);
                  } else {
                      fprintf(stderr, "GET of %s returned http status code %d\n", szUrl, http_status_code);
                  }
      
                  curl_multi_remove_handle(cm, eh);
                  curl_easy_cleanup(eh);
              }
              else {
                  fprintf(stderr, "error: after curl_multi_info_read(), CURLMsg=%d\n", msg->msg);
              }
          }
      
          curl_multi_cleanup(cm);
      
          return EXIT_SUCCESS;
      }

以上就介绍了使用libcurl的正确姿势,包括了方面的内容,希望对C/C++教程有兴趣的朋友有所帮助。

本文网址链接:http://www.codes51.com/article/detail_159678.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值