其他分享
首页 > 其他分享> > HTTP多线程下载

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