当前位置:   article > 正文

curl多线程下载实现

curl多线程下载实现

其实libcurl自带一个应用,很高大上,但是作为范例参考怎么使用libcurl觉得不大适合!还是写一些helloworl的程序的,一目了然......


  1. #include "stdafx.h"
  2. #include <io.h>
  3. #include "curl/curl.h"
  4. #include <string>
  5. #include "curl/easy.h"
  6. #include "pthread.h"
  7. using namespace std;
  8. struct tNode
  9. {
  10. FILE *fp;
  11. int startidx;
  12. int maxidx;
  13. void *_curl;
  14. pthread_t _tid;
  15. };
  16. bool bError = false;
  17. int threadCnt = 0;
  18. static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
  19. static size_t downLoadPackage(void *ptr, size_t size, size_t nmemb, void *userdata)
  20. {
  21. tNode *node = (tNode*)userdata;
  22. size_t written = 0;
  23. pthread_mutex_lock(&foo_mutex);
  24. if ( node->startidx + size * nmemb <= node->maxidx )
  25. {
  26. fseek( node->fp, node->startidx, SEEK_SET );
  27. written = fwrite(ptr, size, nmemb, node->fp);
  28. node->startidx += size * nmemb;
  29. }
  30. else
  31. {
  32. fseek( node->fp, node->startidx, SEEK_SET );
  33. written = fwrite(ptr, 1, node->maxidx - node->startidx + 1, node->fp);
  34. node->startidx = node->maxidx;
  35. }
  36. pthread_mutex_unlock(&foo_mutex);
  37. return written;
  38. }
  39. int assetsManagerProgressFunc(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded)
  40. {
  41. static int percent = 0;
  42. int tmp = 0;
  43. if ( totalToDownload > 0 )
  44. {
  45. tmp = (int)(nowDownloaded / totalToDownload * 100);
  46. }
  47. printf("下载进度%0d%%\r", tmp);
  48. return 0;
  49. }
  50. /************************************************************************/
  51. /* 获取要下载的远程文件的大小 */
  52. /************************************************************************/
  53. long getDownloadFileLenth(const char *url){
  54. double downloadFileLenth = 0;
  55. CURL *handle = curl_easy_init();
  56. curl_easy_setopt(handle, CURLOPT_URL, url);
  57. curl_easy_setopt(handle, CURLOPT_HEADER, 1); //只需要header头
  58. curl_easy_setopt(handle, CURLOPT_NOBODY, 1); //不需要body
  59. if (curl_easy_perform(handle) == CURLE_OK)
  60. {
  61. curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);
  62. }
  63. else
  64. {
  65. downloadFileLenth = -1;
  66. }
  67. return downloadFileLenth;
  68. }
  69. void* workThread(void* pData)
  70. {
  71. tNode* pNode = (tNode*)pData;
  72. int res = curl_easy_perform(pNode->_curl);
  73. if ( res != 0 )
  74. {
  75. }
  76. curl_easy_cleanup(pNode->_curl);
  77. pthread_mutex_lock(&foo_mutex);
  78. threadCnt --;
  79. pthread_mutex_unlock(&foo_mutex);
  80. delete pNode;
  81. pthread_exit(0);
  82. return NULL;
  83. }
  84. bool downLoad(int threadNum, std::string _packageUrl, std::string _storagePath, std::string fileName )
  85. {
  86. long fileLength = getDownloadFileLenth(_packageUrl.c_str());
  87. if ( fileLength <= 0 )
  88. {
  89. printf("get the file error...");
  90. return false;
  91. }
  92. // Create a file to save package.
  93. const string outFileName = _storagePath + fileName;
  94. FILE *fp = fopen(outFileName.c_str(), "wb");
  95. if (! fp)
  96. {
  97. return false;
  98. }
  99. //_chsize((int)fp, fileLength);
  100. int gap = fileLength / threadNum;
  101. for ( int i = 0; i <= threadNum; i ++ )
  102. {
  103. tNode* pNode = new tNode();
  104. if ( i < threadNum )
  105. {
  106. pNode->startidx = i * gap;
  107. pNode->maxidx = pNode->startidx - 1;
  108. }
  109. else
  110. {
  111. if ( fileLength % threadNum != 0 )
  112. {
  113. pNode->startidx = i * gap;
  114. pNode->maxidx = fileLength - 1;
  115. }
  116. }
  117. CURL* _curl = curl_easy_init();
  118. pNode->_curl = _curl;
  119. pNode->fp = fp;
  120. // Download pacakge
  121. curl_easy_setopt(_curl, CURLOPT_URL, _packageUrl.c_str());
  122. curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, downLoadPackage);
  123. curl_easy_setopt(_curl, CURLOPT_WRITEDATA, pNode);
  124. curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, false);
  125. curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, assetsManagerProgressFunc);
  126. //curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this);
  127. curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L);
  128. curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_LIMIT, 1L);
  129. curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_TIME, 5L);
  130. pthread_mutex_lock(&foo_mutex);
  131. threadCnt ++;
  132. pthread_mutex_unlock(&foo_mutex);
  133. int rc = pthread_create (&pNode->_tid, NULL, workThread,pNode);
  134. }
  135. if (bError)
  136. {
  137. fclose(fp);
  138. return false;
  139. }
  140. while (threadCnt >0)
  141. {
  142. Sleep(1000);
  143. }
  144. fclose(fp);
  145. printf("download succed......\n");
  146. return true;
  147. }
  148. int _tmain(int argc, _TCHAR* argv[])
  149. {
  150. downLoad(10, "http://ardownload.adobe.com/pub/adobe/reader/win/11.x/11.0.01/en_US/AdbeRdr11001_en_US.exe", "./", "AdbeRdr11001_en_US.exe");
  151. getchar();
  152. return 0;
  153. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/968679
推荐阅读
相关标签
  

闽ICP备14008679号