• 【玛沁天气】最新玛沁今天天气,实时提供玛沁气温、空气质量、24小时天气预报、生活指数查询 2019-07-24
  • 安徽快3派奖热销 宿州彩民一天两趟忙兑奖 2019-07-24
  • 宜昌朝天吼景区举行国际龙舟漂流大赛 2019-07-10
  • 中国大学生帆船锦标赛大鹏启航 2019-07-10
  • 党的十九大举行第一场记者招待会 介绍加强党建工作和全面从严治党有关情况 2019-07-02
  • 中华人民共和国安全生产法 2019-07-02
  • 网络司法拍卖若违法 当事人受损可申请国家赔偿 2019-07-01
  • 火箭3巨头计划选詹皇or乔治?泡椒3点更兼容灯泡 2019-07-01
  • 世界30座顶级建筑美轮美奂令人叹服 ——凤凰网房产 2019-06-25
  • 端午假期要来了!收藏这份指南,避开人山人海 2019-06-18
  • 华为新平板!MediaPad M5 将配麒麟 960 2019-06-16
  • 【中国梦·大国工匠篇】鸡蛋上钻孔显真功 潜心坚守一线练就绝活儿 2019-06-11
  • 【理上网来·喜迎十九大】塞尔维亚驻华大使:中国的发展是其他国家望尘莫及的 2019-06-10
  • 六大工程培育发展新动能 2019-06-10
  • 为推动上合组织发展提供中国智慧、中国方案 2019-05-29
  • 批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程
    [批处理文件精品]批处理版照片整理器[批处理文件精品]纯批处理备份&还原驱动在线第三方下载
    返回列表 发帖

    广东11选五怎么才中奖:强劲的多线程下载器 purl.exe

    本帖最后由 happy886rr 于 2017-8-26 08:54 编辑
    控制台下强劲的多线程下载器,快如闪电。支持purl.ini配置文件。批量下载各类url资源链。
    用法:
    purl -i[配置文件.ini] -l[输出日志] -n[线程数] -r[根目录]\n\
    配置文件书写格式
    #############################################################################
    //www.a.com/[:0].[:1]
    #############################################################################
    [:0]=01-99
    #############################################################################
    [:1]=jpg,gif,png,bmp
    [:2]=
    [:3]=
    ...
    其中[:0]到[:9]为URL通配符,启用[:0]后具有多线程效益,启用[:9]具有尾加速功能。这10个通配符可以是数字范围如:[:0]=1-9;也可以是字符范围,如[:1]=a-z;还可以是字符串枚举,如:[:2]=jpg,mp3,txt,doc

    为节省论坛空间,不提供任何附件下载,源码发行。
     广东十一选五计划软件 www.qe-ar.com 
    1. /*
    2. THE THREAD DOWNLOAD TOOL, [email protected]~2019 BY HAPPY, VERSION 1.0
    3. PURL.EXE
    4. */
    5. #include   <stdio.h>
    6. #include  <stdlib.h>
    7. #include  <string.h>
    8. #include <windows.h>
    9. #include <process.h>
    10. #include  <direct.h>
    11. #include    <time.h>
    12. #include    <math.h>
    13. #include      <io.h>
    14. #pragma comment(lib, "Ws2_32.lib")
    15. #pragma comment (lib,"urlmon.lib")
    16. /*************宏量定义*************/
    17. #define SAFE_SIZE  512
    18. #define FILE_EXIST 0
    19. //定义配置文件
    20. #define PURL_INI "\
    21. #################################################################\n\
    22. //\n\
    23. #################################################################\n\
    24. [:0]=\n\
    25. #################################################################\n\
    26. [:1]=\n\
    27. [:2]=\n\
    28. [:3]=\n\
    29. [:4]=\n\
    30. [:5]=\n\
    31. [:6]=\n\
    32. [:7]=\n\
    33. [:8]=\n\
    34. #################################################################\n\
    35. [:9]=\n\
    36. #################################################################\n"
    37. //定义帮助说明
    38. #define HELP_INFORMATION "\
    39. -----------------------------------------------------------------\n\
    40. purl -i[inifile] -l[outlog] -n[threadnum] -r[rootdir]\n\
    41. -----------------------------------------------------------------\n\
    42.      -h Show help information\n\
    43.      -i Set the purl inifile\n\
    44.      -l Set the log output directory\n\
    45.      -n Set the number of concurrent threads to download\n\
    46.      -r Set the download root directory\n\
    47. -----------------------------------------------------------------\n\
    48. version 1.0"
    49. /*************全局变量*************/
    50. static int M[10], N[10], Z[10];
    51. static int prointThread=0, nowsThread=0, trueDownload=0, totalCYC=1;
    52. static char murl[SAFE_SIZE], outlog[SAFE_SIZE], inifile[SAFE_SIZE]=".\\purl.ini", mpath[SAFE_SIZE]=".\\", settingini[10][SAFE_SIZE*2], *S[10][SAFE_SIZE];
    53. static BOOL renMARK[10];
    54. static BOOL urlMARK=FALSE;
    55. FILE* logfp;
    56. //进度条容器
    57. static const char* proGRESS="[                                                      ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
    58. /*************事件变量*************/
    59. //创建事件对象
    60. HANDLE ghDataEvent;
    61. /*************功能函数*************/
    62. //切分字串
    63. int ArgsSpliy(char* Str, int SN)
    64. {
    65. int i=0;
    66. char* pstr=strtok(Str, " \t\n,");
    67. while(pstr !=NULL){
    68. S[SN][i]=(char*)calloc(strlen(pstr)+1, sizeof(char));
    69. strcpy(S[SN][i++], pstr);
    70. pstr=strtok(NULL, " \t\n,");
    71. }
    72. return i;
    73. }
    74. //判断字母
    75. BOOL isLetter(char* p)
    76. {
    77. return (p && (('A'<=*p&&*p<='Z')||('a'<=*p&&*p<='z'))&&(*(p+1)=='\0'))?TRUE:FALSE;
    78. }
    79. //彩显函数
    80. int ColorString(HANDLE handle_out, char* pstrA, char* pstrB, int colorA, int colorB, int num)
    81. {
    82. SetConsoleTextAttribute(handle_out, colorA);  //项目色
    83. fprintf(stdout, pstrA);
    84. SetConsoleTextAttribute(handle_out, colorB);  //数据色
    85. (num<0)?fprintf(stdout, pstrB):fprintf(stdout, "%d\n", num);
    86. return 0;
    87. }
    88. //光标函数
    89. BOOL DispyCursor(int size,bool mode)
    90. {
    91. CONSOLE_CURSOR_INFO cinfo ={(DWORD)size, mode};
    92. return SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo);
    93. }
    94. //域名IP解析
    95. int DownloadURLtoIP(HANDLE handle_out, const char* downloadURL)
    96. {
    97. WSADATA wsaData;  
    98. WSAStartup(MAKEWORD(2,2), &wsaData);
    99. char *pstr=(char*)downloadURL, *urlweb=(char*)calloc(SAFE_SIZE, sizeof(char)), *tstr=urlweb;
    100. while(*pstr!=':'){pstr++;}
    101. pstr+=3;
    102. while(*pstr!='/'&& *pstr!='\n' && *pstr!='\0'){
    103. *tstr++=*pstr++;
    104. }
    105. const char* pszUrl=(const char*)urlweb;
    106. if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)  
    107. {
    108. //fprintf(stdout, "Init socket faile\n");  
    109. return 1;  
    110. }
    111. struct hostent *pHost = gethostbyname(pszUrl);
    112. //释放空间
    113. free(urlweb);
    114. if (pHost == NULL)  
    115. {  
    116. WSACleanup();  
    117. //fprintf(stdout, "pHost == NULL \n");  
    118. return 1;  
    119. }
    120. //主机正式名称
    121. ColorString(handle_out, "[URL-HOST] ", (pHost)?pHost->h_name:"NULL", 4|8, 1|2|8, -1);
    122. fprintf(stdout, "\n");
    123. //主机别名,可以有多个
    124. int iIndex = 0;  
    125. while(pHost->h_aliases[iIndex])  
    126. {
    127. ColorString(handle_out, "[URLALIAS] ", pHost->h_aliases[iIndex], 4|8, 1|2|8, -1);
    128. fprintf(stdout, "\n");
    129. iIndex++;  
    130. }
    131. //地址字节数,IPV4是4,IPV6是6
    132. if(pHost->h_length==4)
    133. {
    134. ColorString(handle_out, "[IPV-TYPE] ", "IPV4\n", 4|8, 4|8, -1);
    135. }
    136. else if(pHost->h_length==6)
    137. {
    138. ColorString(handle_out, "[IPV-TYPE] ", "IPV6\n", 4|8, 4|8, -1);
    139. }
    140. iIndex = 0;
    141. while(pHost->h_addr_list[iIndex])  
    142. {
    143. ColorString(handle_out, "[IP-ADDRE] ", inet_ntoa(*(struct in_addr*)pHost->h_addr_list[iIndex]), 4|8, 4|2|8, -1);
    144. fprintf(stdout, "\n");
    145. iIndex++;  
    146. }   
    147. WSACleanup();
    148. return 0;
    149. }
    150. //开关解析
    151. int OPTIND=1, OPTOPT;
    152. char *OPTARG;
    153. int GetOpt(int nargc, char *nargv[], char *ostr)
    154. {
    155. static char* place="";
    156. static char* lastostr=(char *) 0;
    157. register char* oli;
    158. char* index();
    159. if(ostr!=lastostr){
    160. lastostr=ostr;
    161. place="";
    162. }
    163. if(!*place)
    164. {
    165. if(
    166. (OPTIND>=nargc)              ||
    167. (*(place=nargv[OPTIND])!='-')||
    168. (!*(++place))
    169. ){
    170. place="";
    171. return(EOF);
    172. }
    173. if (*place == '-' && place[1] == 0){
    174. ++OPTIND;
    175. return(EOF);
    176. }
    177. }
    178. if ((OPTOPT=(int)*place++)==(int)':' || !(oli=strchr(ostr, OPTOPT))){
    179. if(!*place){++OPTIND;}
    180. }
    181. if (oli != NULL && *(++oli) != ':'){
    182. OPTARG=NULL;
    183. if(!*place){++OPTIND;}
    184. }
    185. else{
    186. if(*place){
    187. OPTARG=place;
    188. }else if(nargc<=++OPTIND){
    189. place="";
    190. }else{
    191. OPTARG=nargv[OPTIND];
    192. }
    193. place="";
    194. ++OPTIND;
    195. }
    196. return(OPTOPT);
    197. }
    198. /*************获取配置*************/
    199. int ReadSetting(char* pfile)
    200. {
    201. //读取脚本文件
    202. FILE* fp;
    203. if( (fp=fopen(pfile, "r"))==NULL ){
    204. fprintf(stdout, "Reading settings failed!\n");
    205. exit(1);
    206. }
    207. int SN;
    208. //分配行容器
    209. char* LCache=(char*)calloc(1025, sizeof(char));
    210. //辅助行指针
    211. char* Line=NULL;
    212. while(!feof(fp)){
    213. memset(LCache, 0,  1024*sizeof(char));
    214. fgets(LCache, 1024, fp);
    215. //指针置换
    216. Line=LCache;
    217. //将尾部换行符注掉
    218. while(*Line!='\n'&& *Line!='\0'){Line++;}
    219. *Line='\0';
    220. Line=LCache;
    221. //过滤行TAB缩进或前空格
    222. while(*Line=='\t'|| *Line==' '){Line++;}
    223. //过滤注释符
    224. if(Line[0]=='#'||strlen(Line)<=5){
    225. continue;
    226. }
    227. //提取URL
    228. if(
    229. (!urlMARK)                    &&
    230. (Line[0]=='h' ||Line[0]=='H') &&
    231. (Line[1]=='t' ||Line[1]=='T') &&
    232. (Line[2]=='t' ||Line[2]=='T') &&
    233. (Line[3]=='p' ||Line[3]=='P') &&
    234. (
    235. Line[4]==':' ||
    236. (
    237. (Line[4]=='s'||Line[4]=='S') &&
    238. (Line[5]==':')
    239. )
    240. )
    241. ){
    242. if(strlen(Line)<10){
    243. fprintf(stdout, "Please fill the url!\n");
    244. exit(1);
    245. }
    246. strcpy(murl, Line);
    247. while(*Line !='\0'){
    248. if(*Line=='[' && *(Line+1)==':' && ('0'<=*(Line+2) && *(Line+2)<='9') && *(Line+3)==']'){
    249. renMARK[*(Line+2)-48]=TRUE;
    250. Line+=4;
    251. }else{
    252. Line++;
    253. }
    254. }
    255. urlMARK=TRUE;
    256. continue;
    257. }else if(
    258. (urlMARK)                     &&
    259. (Line[0]=='[' &&Line[1]==':') &&
    260. ('0'<=Line[2] &&Line[2]<='9') &&
    261. (Line[3]==']' &&Line[4]=='=')
    262. ){
    263. SN=Line[2]-48;
    264. if(!renMARK[SN]){continue;}
    265. strcpy(settingini[SN], Line);
    266. if(strchr(Line+5, ',')){
    267. M[SN]=0;
    268. N[SN]=ArgsSpliy(Line+5, SN)-1;
    269. }else if(renMARK[SN]){
    270. char *snumsrc=strtok(Line+5, " \t-"), *tmps=(snumsrc!=NULL)?strtok(NULL, " \t-"):NULL, *zp=snumsrc;
    271. if(isLetter(snumsrc) && isLetter(tmps)){
    272. int exnum1=*snumsrc, exnum2=*tmps;
    273. Z[SN]=-1;
    274. M[SN]=(exnum1 <= exnum2)?(N[SN]=exnum2, exnum1):(N[SN]=exnum1, exnum2);
    275. }else if(tmps!=NULL){
    276. if(*zp=='0'){
    277. while('0'<= *zp && *zp <='9'){
    278. Z[SN]++;
    279. zp++;
    280. }
    281. }
    282. M[SN]=atoi(snumsrc), N[SN]=atoi(tmps);
    283. if(M[SN]>N[SN]){
    284. int exnum=M[SN];
    285. M[SN]=N[SN], N[SN]=exnum;
    286. }
    287. }
    288. }
    289. }
    290. }
    291. fclose(fp);
    292. //统计总循环次数
    293. for(int i=0; i<10; i++){totalCYC *=N[i]-M[i]+1;}
    294. return 0;
    295. }
    296. /*************下载函数*************/
    297. UINT WINAPI FastDownload(void* ptr)
    298. {
    299. //分配URL字串
    300. char* ptftr=(char*)calloc(16, sizeof(char));
    301. char* aurl =(char*)calloc(SAFE_SIZE, sizeof(char));
    302. char* dest =(char*)calloc(SAFE_SIZE, sizeof(char));
    303. char* durl =(char*)calloc(SAFE_SIZE, sizeof(char));
    304. char* titl =(char*)calloc(SAFE_SIZE, sizeof(char));
    305. durl[0]='.', durl[1]='\\';
    306. //接受线程传参
    307. int nThreadID = *((int*)ptr);
    308. int snum      = *((int*)ptr+1);
    309. int lnum      = *((int*)ptr+2);
    310. SetEvent(ghDataEvent);
    311. nowsThread++;
    312. if(*outlog != 0){
    313. //fprintf(logfp, "\nThe %dth thread start.\n", nThreadID+1);
    314. }
    315. //创建循环变量数组
    316. int i[10]={0}, SN;
    317. //创建下载状态变量
    318. BOOL preMARK=FALSE, nowMARK=FALSE;
    319. //定义URL指针
    320. char *purl=NULL, *surl=NULL, *pdit=NULL;
    321. //启动十层循环
    322. for(i[0]=snum; i[0]<=lnum; i[0]++)
    323. for(i[1]=M[1]; i[1]<=N[1]; i[1]++)
    324. for(i[2]=M[2]; i[2]<=N[2]; i[2]++)
    325. for(i[3]=M[3]; i[3]<=N[3]; i[3]++)
    326. for(i[4]=M[4]; i[4]<=N[4]; i[4]++)
    327. for(i[5]=M[5]; i[5]<=N[5]; i[5]++)
    328. for(i[6]=M[6]; i[6]<=N[6]; i[6]++)
    329. for(i[7]=M[7]; i[7]<=N[7]; i[7]++)
    330. for(i[8]=M[8]; i[8]<=N[8]; i[8]++)
    331. for(i[9]=M[9]; i[9]<=N[9]; i[9]++){
    332.     surl=murl, purl=aurl;
    333. while(*surl !='\0'){
    334. //替换正则标签
    335. if(*surl=='[' && *(surl+1)==':' && '0'<=*(surl+2) && *(surl+2)<='9' && *(surl+3)==']' && renMARK[*(surl+2)-48]){
    336. SN=*(surl+2)-48;
    337. if(S[SN][0] !=NULL){
    338. pdit=S[SN][i[SN]];
    339. }else{
    340. if(Z[SN] >0){
    341. sprintf(ptftr, "%%0%dd", Z[SN]);
    342. sprintf(dest, ptftr, i[SN]);
    343. }else if(Z[SN]==-1){
    344. sprintf(dest, "%c",  (char)i[SN]);
    345. }else{
    346. sprintf(dest, "%d",  i[SN]);
    347. }
    348. pdit=dest;
    349. }
    350. while(*pdit !='\0'){
    351. *(purl++)=*(pdit++);
    352. }
    353. surl+=4;
    354. }else{
    355. *(purl++)=*(surl++);
    356. }
    357. }
    358. //置结束符
    359. *purl='\0';
    360. //显示当前下载的URL
    361. prointThread++;
    362. sprintf(titl, "[%03dT]-[%03dF] %s", nowsThread, trueDownload, aurl);
    363. SetConsoleTitleA(titl);
    364. //处理下载路径
    365. char* turl=strstr(aurl, "://")+3;
    366. char* sp=durl+2;
    367. //根据网址创建目录
    368. while(*turl != '\0'){
    369. switch(*turl)
    370. {
    371. case '/':
    372. *sp='\0';
    373. if(_access(durl, FILE_EXIST) != 0){
    374. _mkdir(durl);
    375. }
    376. *sp='\\';
    377. break;
    378. case ':':
    379. case '*':
    380. case '?':
    381. case '"':
    382. case '>':
    383. case '<':
    384. case '|':
    385. *sp='@';
    386. break;
    387. default:
    388. *sp=*turl;
    389. break;
    390. }
    391. //指针移位
    392. sp++, turl++;
    393. }
    394. //置结束符
    395. *sp='\0';
    396. //调用API下载
    397. URLDownloadToFileA(NULL, aurl, durl, 0, NULL);
    398. //下载状态
    399. nowMARK=(_access(durl, FILE_EXIST)==0)?TRUE:FALSE;
    400. //增速判断
    401. if(preMARK && !nowMARK && i[9]!=M[9]){
    402. break;
    403. }
    404. //显示下载成功的文件
    405. if(nowMARK){
    406. trueDownload++;
    407. if(*outlog != 0){fprintf(logfp, "[*]%s\n", aurl);}
    408. }
    409. //下载状态更新
    410. preMARK=nowMARK;
    411. }
    412. //释放数组内存
    413. free(aurl);
    414. free(durl);
    415. free(dest);
    416. free(titl);
    417. free(ptftr);
    418. //线程结束
    419. nowsThread--;
    420. if(*outlog != 0){
    421. //fprintf(logfp, "\nThe %dth thread end!\n\n", nThreadID+1);
    422. }
    423. return (UINT)0;
    424. }
    425. /*************MAIN函数*************/
    426. int main(int argc, char** argv)
    427. {
    428. int threadNUMS=100;
    429. char K, *outLOG=NULL;
    430. while((K=GetOpt(argc,argv,"hi:n:p:l:"))!=-1)
    431. {
    432. switch(K)
    433. {
    434. case 'h':
    435. case 'H':
    436. fprintf(stdout, HELP_INFORMATION);
    437. exit(0);
    438. case 'i':
    439. case 'I':
    440. if(OPTARG !=NULL){
    441. strcpy(inifile, OPTARG);
    442. }
    443. break;
    444. case 'l':
    445. case 'L':
    446. if(OPTARG !=NULL){
    447. strcpy(outlog, OPTARG);
    448. }
    449. break;
    450. case 'n':
    451. case 'N':
    452. if(OPTARG !=NULL){
    453. int exnum=atoi(OPTARG);
    454. threadNUMS=(0<exnum && exnum<SAFE_SIZE*4)?exnum:SAFE_SIZE*4;
    455. }
    456. break;
    457. case 'r':
    458. case 'R':
    459. if(OPTARG !=NULL){
    460. strcpy(mpath, OPTARG);
    461. }
    462. break;
    463. default:
    464. fprintf(stdout, "Unknown switch '%c'\n", K);
    465. exit(1);
    466. }
    467. }
    468. //判断配置文件是否存在
    469. if(access(inifile, FILE_EXIST)!=0){
    470. FILE* fp=fopen(inifile, "w");
    471. fprintf(fp, PURL_INI);
    472. fclose(fp);
    473. fprintf(stdout, "Please fill in the setting file\n");
    474. fprintf(stdout, HELP_INFORMATION);
    475. exit(1);
    476. }
    477. if(argc==1){
    478. //无参数则退出
    479. fprintf(stdout, HELP_INFORMATION);
    480. exit(0);
    481. }
    482. //判断根目录是否存在
    483. if(_access(mpath, FILE_EXIST)!=0){
    484. _mkdir(mpath);
    485. }
    486. if(_access(mpath, FILE_EXIST)==0){
    487. //切换至下载目录
    488. _chdir(mpath);
    489. }else{
    490. //无法创建根目录则退出
    491. fprintf(stdout, "Can not creat the root folder\n");
    492. exit(1);
    493. }
    494. //读取purl配置文件
    495. ReadSetting(inifile);
    496. if(! urlMARK){
    497. fprintf(stdout, "Please fill in the download url\n");
    498. exit(1);
    499. }
    500. //获取控制台输出句柄
    501. HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE);
    502. //线程传参数组
    503. int inum[3]={0};
    504. //判断是否使用多线程正则符[:0]
    505. if(! renMARK[0]){
    506. threadNUMS=1;
    507. }
    508. //线程数
    509. int nThreadCount=N[0]-M[0];
    510. if(nThreadCount<=0 && threadNUMS!=1){
    511. fprintf(stdout, "\nThe '[:0]' don't get incremental value\n");
    512. exit(1);
    513. }
    514. //创建时间结构体
    515. time_t startTIME, endTIME;
    516. struct tm* timeinfo;
    517.         time(&startTIME);
    518.         timeinfo=localtime(&startTIME);
    519. //计算线程分组数
    520. int rThreadAdd   =(int)ceil((nThreadCount + 1)*1.0/threadNUMS);
    521. int rThreadRange =(int)ceil((nThreadCount + 1)*1.0/(rThreadAdd?rThreadAdd:1.0));
    522. //是否开启日志输出
    523. if(*outlog != 0){
    524. logfp=fopen(outlog, "w");
    525. if(logfp == NULL){
    526. fprintf(stdout, "Open log failed\n");
    527. exit(1);
    528. }else{
    529. fprintf(logfp,
    530. "================================================================\n"
    531. "The purl log file, Time: %s"
    532. "================================================================\n\n"
    533. ,asctime(timeinfo)
    534. );
    535. fprintf(logfp, "[Threads num]\n%d\n\n", rThreadRange);
    536. fprintf(logfp, "[Root path]\n%s\n\n", mpath);
    537. fprintf(logfp, "[The URL regular]\n%s\n\n", murl);
    538. fprintf(logfp, "[Setting ini]\n");
    539. for(int i=0; i<=9; i++){
    540. if(settingini[i][0]!=0){
    541. fprintf(logfp, "%s\n", settingini[i]);
    542. }
    543. }
    544. fprintf(logfp, "\n[Start the download time]\n%s\n", asctime(timeinfo));
    545. fprintf(logfp, "[Successfully downloaded URL]\n");
    546. }
    547. }
    548. //隐藏光标
    549. DispyCursor((DWORD)25, FALSE);
    550. //显示目标网站IP
    551. DownloadURLtoIP(handle_out, murl);
    552. //分配线程句柄数组
    553. HANDLE* phaThread =(HANDLE*)calloc(rThreadRange, sizeof(HANDLE));
    554. //创建事件对象
    555. ghDataEvent =CreateEventA(NULL, FALSE, FALSE, NULL);
    556. //错误号
    557. int nErr=0;
    558. for(int i=0; i<rThreadRange; i++){
    559. inum[0]=i, inum[1]=M[0]+i*rThreadAdd, inum[2]=M[0]+i*rThreadAdd+rThreadAdd-1;
    560. if(inum[2]>N[0]){inum[2]=N[0];}
    561. phaThread[i]=(HANDLE)_beginthreadex(NULL, 0, FastDownload, &inum, 2048, NULL);
    562. if(phaThread[i]==0){
    563.              nErr=GetLastError();
    564.              if(nErr==0x08){
    565.        printf("\nOpen thread failed, lack of storage space!\n");
    566. }else{
    567. printf("\nOpen thread failed, error number%d\n", nErr);
    568. }
    569. break;
    570. }
    571. WaitForSingleObject(ghDataEvent, INFINITE);
    572. }
    573. //色彩代码 紫色1|4|8,红色4|8,绿色2|8,兰色1|2|8,黄色2|4|8,白色1|2|4|8;
    574. //显示最大线程
    575. ColorString(handle_out, "[MAX-THRE] ", "", 4|8, 4|8, rThreadRange);
    576. //显示开始时间
    577. ColorString(handle_out, "[STA-TIME] ", asctime(timeinfo), 4|8, 1|4|8, -1);
    578. //绘制进度框
    579. ColorString(handle_out, "[DOWNLOAD] ", (char*)proGRESS, 4|8, 2|4|8, -1);
    580. //绘制进度条
    581. int spi=0;
    582. do{
    583. //进度百分数
    584. int i=(totalCYC==0)?100:(prointThread*100/totalCYC), j=i/2;
    585. if(spi==j){
    586. //缓解CPU占用
    587. Sleep(30);
    588. continue;
    589. }
    590. //显示递增进度
    591. while(spi<j){
    592. fputc('=', stdout);
    593. spi++;
    594. }
    595. //显示进度百分比
    596. fprintf(stdout, "%3d%%\b\b\b\b", i);
    597. //线程退出器
    598. if(prointThread==totalCYC){
    599. break;
    600. }
    601. }while(nowsThread);
    602. //补全百分百进度
    603. if(prointThread==totalCYC){
    604. while(spi<50){
    605. fputc('=', stdout);
    606. spi++;
    607. }
    608. fprintf(stdout, "100%%");
    609. }
    610. fprintf(stdout, "\n");
    611. //显示结束时间
    612. time(&endTIME);
    613. timeinfo=localtime(&endTIME);
    614. ColorString(handle_out, "[END-TIME] ", asctime(timeinfo), 4|8, 1|4|8, -1);
    615. //显示花费时间
    616. ColorString(handle_out, "[USE-TIME] ", "", 4|8, 1|2|8, -1);
    617. fprintf(stdout, "Takes %gs\n", difftime(endTIME, startTIME));
    618. //颜色归位
    619. SetConsoleTextAttribute(handle_out, 1|2|4);//白色
    620. //关闭日志读写
    621. if(*outlog != 0){
    622. fprintf(logfp, "\n[End the download time]\n%s\n", asctime(timeinfo));
    623. fprintf(logfp, "[Download time-spending]\n%g seconds\n\n", difftime(endTIME, startTIME));
    624. fprintf(logfp, "[Percent of completion]\n%d%%\n\n", (prointThread==totalCYC)?100:spi*2);
    625. fprintf(logfp, "[Successfully downloaded files]\n%d", trueDownload);
    626. fclose(logfp);
    627. }
    628. return 0;
    629. }
    复制代码
    2

    评分人数

    本帖最后由 freesoft00 于 2017-8-26 01:18 编辑


    是我用错了吗?怎么不行。

    https://download.mozilla.org/?product=firefox-55.0.3-SSL&os=win&lang=zh-CN
    //ftp.mozilla.org/pub/firefox/releases/55.0.3/win32/zh-CN/Firefox%20Setup%2055.0.3.exe
    https://ipmsg.org/archive/ipmsg470src.zip


    把这三个网址分别添加到purl.ini中,也不行。弹出错误。
    附件: 您需要登录才可以下载或查看附件。没有帐号?注册

    TOP

    本帖最后由 happy886rr 于 2017-8-26 09:07 编辑

    回复 2# freesoft00
    代码已经修复,这是多线程批量下载器,只支持批量地址下载,比如www.a01.com, www.a02.com, www.a03.com就是批量的网址,而不是说单一下载某个文件。
    单独下载某个文件请使用pget。
    purl的目的是针对有规律的数字递增网址,批量多线程下载,而且必须是几千、几万的批量网址才可以成功下载。线程过少的话,主程序很快就跑完了,子线程也就结束了。我把下载量调到5000,你的文件都成功下载了[:0]=0-5000
    purl是针对繁重的批量下载任务定制的,个别几个小文件的下载多线程会得不偿失,小文件请使用pget。

    TOP

    回复 3# happy886rr


        哦,知道了。用途不一样呀。

    TOP

    支持  ssh 链接的 sftp  下载吗?

    TOP

    请教下要怎么编译?
    gcc和vs均未通过

    TOP

    本帖最后由 523066680 于 2017-10-10 10:02 编辑

    回复 6# CrLf


        试了 MinGW GCC, 稍微改一下可以

    添加 <stdbool.h>
    注释掉两个 lib 的引入(改为手动)
    1. #include <stdbool.h>
    2. // #pragma comment(lib, "ws2_32.lib")
    3. // #pragma comment (lib,"urlmon.lib")
    复制代码
    gcc purl.c -lws2_32 -lurlmon
    综合型编程论坛
    Writing Code That Nobody Else Can Read.

    TOP

    本帖最后由 happy886rr 于 2017-10-10 14:10 编辑

    回复 6# CrLf
    大师,好久不见。(后缀一定要改为cpp)
    编译现在都已经实现一键了,请参看我之前的帖子//www.qe-ar.com/thread-44180-1-1.html
    下载那个精简的vc++2010编译器(仅22M大?。?,把.cpp文件直接拖拽到VC.CMD批处理脚本上,就会自动生成exe。
    别看体积小,编译功能与原版VS几乎没有差别。
       
    另外我还发布过手机版的gcc编译器,可以实现代码直接编译为 安卓上可运行的二进制文件。从而实现 win、linux、安卓 各平台通吃。
    1

    评分人数

    TOP

    回复 8# happy886rr

    手机版本的编译器在哪里?

    TOP

    返回列表
  • 【玛沁天气】最新玛沁今天天气,实时提供玛沁气温、空气质量、24小时天气预报、生活指数查询 2019-07-24
  • 安徽快3派奖热销 宿州彩民一天两趟忙兑奖 2019-07-24
  • 宜昌朝天吼景区举行国际龙舟漂流大赛 2019-07-10
  • 中国大学生帆船锦标赛大鹏启航 2019-07-10
  • 党的十九大举行第一场记者招待会 介绍加强党建工作和全面从严治党有关情况 2019-07-02
  • 中华人民共和国安全生产法 2019-07-02
  • 网络司法拍卖若违法 当事人受损可申请国家赔偿 2019-07-01
  • 火箭3巨头计划选詹皇or乔治?泡椒3点更兼容灯泡 2019-07-01
  • 世界30座顶级建筑美轮美奂令人叹服 ——凤凰网房产 2019-06-25
  • 端午假期要来了!收藏这份指南,避开人山人海 2019-06-18
  • 华为新平板!MediaPad M5 将配麒麟 960 2019-06-16
  • 【中国梦·大国工匠篇】鸡蛋上钻孔显真功 潜心坚守一线练就绝活儿 2019-06-11
  • 【理上网来·喜迎十九大】塞尔维亚驻华大使:中国的发展是其他国家望尘莫及的 2019-06-10
  • 六大工程培育发展新动能 2019-06-10
  • 为推动上合组织发展提供中国智慧、中国方案 2019-05-29
  • 深圳风采39期 北京快三大小分析 玩北京快乐8稳赚技巧 江苏快3预测软件免费 彩票中心官网 rain急速赛车 福建快3遗漏数据 波叔、一波中特2019年81期 头条彩票官网首页 福彩30选5开奖时间 广西快3遗漏值统计快3广西风采网 北京pk10号码预测神器 大乐透在那个台开奖直播 新疆时时彩每天几期 香港六合彩网站