今天写了个多线程的文件下载器,可以自定义线程数,不废话,看代码: #include <iostream> #include "windows.h" #include "wininet.h" using namespace std; #pragma comment(lib,"wininet.lib") struct file{ DWORD start; DWORD len; char url[1024]; char localfile[1024]; }; DWORD totle=0; CRITICAL_SECTION cs; DWORD WINAPI down(LPVOID lp){ file *ff=(file*)lp; int len=ff->len,l=0; int start=ff->start; DWORD read=0; char b[100]={0}; HINTERNET ie=InternetOpen("sx",INTERNET_OPEN_TYPE_PRECONFIG,0,0,0); HINTERNET ieo=InternetOpenUrl(ie,ff->url,0,0,INTERNET_FLAG_RELOAD,0); int off=InternetSetFilePointer(ieo,start,0,FILE_BEGIN,0); FILE *f=fopen(ff->localfile,"rb+"); int sk=fseek(f,start,SEEK_SET); while(1){ if(l+100<=len){ InternetReadFile(ieo,b,100,&read); }else{ InternetReadFile(ieo,b,len-l,&read); } l+=read; if(read==0){ break; } fwrite(b,1,read,f); EnterCriticalSection(&cs); totle+=read; LeaveCriticalSection(&cs); Sleep(1); } fclose(f); InternetCloseHandle(ieo); InternetCloseHandle(ie); delete ff; return 0; } main(){ InitializeCriticalSection(&cs); char url[1024],localfile[1024]; int threads; gets(url); gets(localfile); cin>>threads; HINTERNET ie=InternetOpen("sx",INTERNET_OPEN_TYPE_PRECONFIG,0,0,0); HINTERNET ieo=InternetOpenUrl(ie,url,0,0,INTERNET_FLAG_RELOAD,0); DWORD len1,len2; HttpQueryInfo(ieo,HTTP_QUERY_CONTENT_LENGTH| HTTP_QUERY_FLAG_NUMBER,&len1,&len2,0); InternetCloseHandle(ieo); InternetCloseHandle(ie); HANDLE f=CreateFile(localfile,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); SetFilePointer(f,len1,0,FILE_BEGIN); SetEndOfFile(f); CloseHandle(f); HANDLE *dh=new HANDLE[threads]; for(int i=0;i<threads;i++){ file *ff=new file; if(threads>1){ ff->len=i<(threads-1)?len1/(threads-1):(len1-len1/(threads-1)*(threads-1)); ff->start=i*(len1/(threads-1)); }else{ ff->len=len1; ff->start=0; } strcpy(ff->localfile,localfile); strcpy(ff->url,url); dh[i]=CreateThread(0,0,down,(LPVOID)ff,0,0); } while(totle%len1!=0 || totle==0){ cout<<totle*1.0/len1*100<<"%"<<endl; Sleep(200); } WaitForMultipleObjects(threads,dh,true,-1); delete[] dh; DeleteCriticalSection(&cs); /* file *ff=new file; ff->len=len1; ff->start=0; strcpy(ff->localfile,"c://a.gif"); strcpy(ff->url,"http://www.baidu.com/img/baidu_logo.gif"); down((LPVOID)ff);*/ cout<<len1<<endl; } 测试了下,效果不错。还可以显示下载进度,还算比较满意吧。 文章有不足之处,还望大家多多指正。