HTTP多线程下载
作者:互联网
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#pragma comment(lib,"wininet.lib")
#define THREADNUM 4
#define BUFLEN 1024
struct stFile{
DWORD start;
DWORD len;
TCHAR url[MAX_PATH];
TCHAR localfile[MAX_PATH];
};
DWORD nTotleSize=0;
CRITICAL_SECTION criticalsection;
DWORD WINAPI DownloadThread(LPVOID lp){
stFile *stfile = (stFile*)lp;
int nCount = stfile->len;
int nLen = 0;
int start = stfile->start;
DWORD readsize = 0;
BYTE buffer[BUFLEN] = {0};
HINTERNET hInternet=InternetOpen(TEXT("RookIE/1.0"),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
HINTERNET hUrl=InternetOpenUrl(hInternet,stfile->url,0,0,INTERNET_FLAG_RELOAD,0);
InternetSetFilePointer(hUrl,start,0,FILE_BEGIN,0);
FILE *fp=_tfopen(stfile->localfile,TEXT("rb+"));
fseek(fp,start,SEEK_SET);
while(TRUE){
if(nLen+BUFLEN<=nCount){
InternetReadFile(hUrl,buffer,BUFLEN,&readsize);
}else{
InternetReadFile(hUrl,buffer,nCount-nLen,&readsize);
}
nLen+=readsize;
if(readsize==0){
break;
}
fwrite(buffer,1,readsize,fp);
EnterCriticalSection(&criticalsection);
nTotleSize+=readsize;
LeaveCriticalSection(&criticalsection);
Sleep(0);
}
fclose(fp);
InternetCloseHandle(hUrl);
InternetCloseHandle(hInternet);
delete stfile;
return 0;
}
void HttpDownload(TCHAR *szUrl, TCHAR *localfile) {
DWORD nStart = GetTickCount();
InitializeCriticalSection(&criticalsection);
HINTERNET hInternet=InternetOpen(TEXT("RookIE/1.0"),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
HINTERNET hUrl=InternetOpenUrl(hInternet,szUrl,0,0,INTERNET_FLAG_RELOAD,0);
DWORD nCount = 0;
DWORD dwSize = sizeof(nCount);
HttpQueryInfo(hUrl,HTTP_QUERY_CONTENT_LENGTH| HTTP_QUERY_FLAG_NUMBER,(LPVOID)&nCount,&dwSize,0);
InternetCloseHandle(hUrl);
InternetCloseHandle(hInternet);
HANDLE hFile=CreateFile(localfile,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
SetFilePointer(hFile,nCount,0,FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
HANDLE *dThread=new HANDLE[THREADNUM];
for(int i=0;i<THREADNUM;i++){
stFile *stfile=new stFile;
if(THREADNUM>1){
stfile->len=i<(THREADNUM-1)?nCount/(THREADNUM-1):(nCount-nCount/(THREADNUM-1)*(THREADNUM-1));
stfile->start=i*(nCount/(THREADNUM-1));
}else{
stfile->len=nCount;
stfile->start=0;
}
_tcscpy(stfile->localfile,localfile);
_tcscpy(stfile->url,szUrl);
dThread[i]=CreateThread(0,0,DownloadThread,(LPVOID)stfile,0,0);
}
while(nTotleSize%nCount!=0 || nTotleSize==0){
DWORD nTime = GetTickCount()-nStart;
printf("%3.5f%%, %0.2fKB/s\r\n", nTotleSize*1.0/nCount*100, nTotleSize*1.0/nTime*1000/1024);
Sleep(1000);
}
WaitForMultipleObjects(THREADNUM,dThread,true,-1);
delete[] dThread;
DeleteCriticalSection(&criticalsection);
DWORD nTime = GetTickCount()-nStart;
printf("%3.5f%%, %0.2fKB/s\r\n", nTotleSize*1.0/nCount*100, nTotleSize*1.0/nTime*1000/1024);
}
标签:HTTP,nTotleSize,nCount,start,stfile,DWORD,1.0,多线程,下载 来源: https://blog.51cto.com/u_15298588/3034071