发一个多线程通过 HTTP 下载文件的类(Linux下的实现)
多线程下载文件这个话题已经是老汤了。在HTTP协议1.1中,允许通过增加一个HTTP Header“Range”来指定下载文件的区间。
所以一般的做法都是:
[*]首先获取到文件大小(通过Content-Length)
[*]开一个线程池在进行分块下载。
而在具体怎么实现的流程上,还是有差别的。
1. 标准的做法是:首先用一个线程发送HTTP GET指令,服务器会返回Content-Length,并能够根据协议判断出服务器是否支持Range。如果支持Range,则调配其它线程对后续部分分块下载。第一个线程继续下载第1块。
2. 还一种做法,首先发送HTTP HEAD指令,通过返回的Content-Length进行分块,调配线程进行下载。
这里提供一个类,属于第2种。
为了提高IO性能,类中可以使用内存映射文件方式进行操作。
<div class="highlighter">
[*]#ifndefCHTTPFILEDOWNLOADER_H_
[*]#defineCHTTPFILEDOWNLOADER_H_
[*]
[*]#include"Generic.h"
[*]
[*]classCHttpFileDownloader{
[*]public:
[*]CHttpFileDownloader();
[*]virtual~CHttpFileDownloader();
[*]
[*]booldownloadUrlToFile(constchar*lpszUrl,constchar*lpszFile);
[*]boolwaitForCompletion(void);
[*]
[*]private:
[*]stringm_strLocalFile;
[*]pthread_tm_lLeaderThread;
[*]structsockaddr_inm_stServerAddr;
[*]charm_szResourceURI;
[*]charm_szDomain;
[*]charm_szHost;
[*]charm_szUrl;
[*]
[*]sem_tm_stDownSem;
[*]pthread_mutex_tm_stDownloadThreadMutex;
[*]intm_nDownloadThreadCnt;
[*]boolm_bFailed;
[*]sem_tm_stCompleteSem;
[*]boolm_bSuccess;
[*]
[*]staticvoid*leaderThread(void*param);
[*]staticvoid*downloadThread(void*param);
[*]booldownloadProcess(void);
[*]voiddownloadBlock(unsignedchar*pMemory,intnRangeStart,intnRangeSize);
[*]
[*]boolsendBuffer(intnSocket,char*pBuf,intnSize);
[*]boolsendStringStream(intnSocket,stringstream&oStream);
[*]intrecvStringStream(intnSocket,stringstream&oStream);
[*]std::vector<string>parseResponse(stringstrResponse);
[*]boolisHttpStatusSuccess(string&strHttpResponse);
[*]stringgetHeaderValueByName(constchar*lpszHeader,std::vector<string>&vItems);
[*]
[*]};
[*]
[*]#endif/*CHTTPFILEDOWNLOADER_H_*/
[*]
页:
[1]