linux libcurl 多线程,curl多线程下载实现

这个博客展示了如何使用libcurl库在C++中实现多线程下载文件。通过创建线程并利用libcurl的回调函数,程序能够分块下载文件,并实时更新下载进度。下载过程中使用互斥锁确保线程安全。最后,所有线程完成后,文件下载成功。
摘要由CSDN通过智能技术生成

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

#include "stdafx.h"

#include

#include "curl/curl.h"

#include

#include "curl/easy.h"

#include "pthread.h"

using namespace std;

struct tNode

{

FILE *fp;

int startidx;

int maxidx;

void *_curl;

pthread_t _tid;

};

bool bError = false;

int threadCnt = 0;

static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;

static size_t downLoadPackage(void *ptr, size_t size, size_t nmemb, void *userdata)

{

tNode *node = (tNode*)userdata;

size_t written = 0;

pthread_mutex_lock(&foo_mutex);

if ( node->startidx + size * nmemb <= node->maxidx )

{

fseek( node->fp, node->startidx, SEEK_SET );

written = fwrite(ptr, size, nmemb, node->fp);

node->startidx += size * nmemb;

}

else

{

fseek( node->fp, node->startidx, SEEK_SET );

written = fwrite(ptr, 1, node->maxidx - node->startidx + 1, node->fp);

node->startidx = node->maxidx;

}

pthread_mutex_unlock(&foo_mutex);

return written;

}

int assetsManagerProgressFunc(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded)

{

static int percent = 0;

int tmp = 0;

if ( totalToDownload > 0 )

{

tmp = (int)(nowDownloaded / totalToDownload * 100);

}

printf("下载进度%0d%%\r", tmp);

return 0;

}

/************************************************************************/

/* 获取要下载的远程文件的大小            */

/************************************************************************/

long getDownloadFileLenth(const char *url){

double downloadFileLenth = 0;

CURL *handle = curl_easy_init();

curl_easy_setopt(handle, CURLOPT_URL, url);

curl_easy_setopt(handle, CURLOPT_HEADER, 1);    //只需要header头

curl_easy_setopt(handle, CURLOPT_NOBODY, 1);    //不需要body

if (curl_easy_perform(handle) == CURLE_OK)

{

curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);

}

else

{

downloadFileLenth = -1;

}

return downloadFileLenth;

}

void* workThread(void* pData)

{

tNode* pNode = (tNode*)pData;

int res = curl_easy_perform(pNode->_curl);

if ( res != 0 )

{

}

curl_easy_cleanup(pNode->_curl);

pthread_mutex_lock(&foo_mutex);

threadCnt --;

pthread_mutex_unlock(&foo_mutex);

delete pNode;

pthread_exit(0);

return NULL;

}

bool downLoad(int threadNum, std::string _packageUrl, std::string _storagePath, std::string fileName )

{

long fileLength = getDownloadFileLenth(_packageUrl.c_str());

if ( fileLength <= 0 )

{

printf("get the file error...");

return false;

}

// Create a file to save package.

const string outFileName = _storagePath + fileName;

FILE *fp = fopen(outFileName.c_str(), "wb");

if (! fp)

{

return false;

}

//_chsize((int)fp, fileLength);

int gap = fileLength / threadNum;

for ( int i = 0; i <= threadNum; i ++ )

{

tNode* pNode = new tNode();

if ( i < threadNum )

{

pNode->startidx = i * gap;

pNode->maxidx = pNode->startidx - 1;

}

else

{

if ( fileLength % threadNum != 0 )

{

pNode->startidx = i * gap;

pNode->maxidx = fileLength - 1;

}

}

CURL* _curl = curl_easy_init();

pNode->_curl = _curl;

pNode->fp = fp;

// Download pacakge

curl_easy_setopt(_curl, CURLOPT_URL, _packageUrl.c_str());

curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, downLoadPackage);

curl_easy_setopt(_curl, CURLOPT_WRITEDATA, pNode);

curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, false);

curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, assetsManagerProgressFunc);

//curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this);

curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L);

curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_LIMIT, 1L);

curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_TIME, 5L);

pthread_mutex_lock(&foo_mutex);

threadCnt ++;

pthread_mutex_unlock(&foo_mutex);

int rc = pthread_create (&pNode->_tid, NULL, workThread,pNode);

}

if (bError)

{

fclose(fp);

return false;

}

while (threadCnt >0)

{

Sleep(1000);

}

fclose(fp);

printf("download succed......\n");

return true;

}

int _tmain(int argc, _TCHAR* argv[])

{

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");

getchar();

return 0;

}

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值