⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 下载程序,多线程下载,断点续传. 目前只能下http
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <unistd.h>#include <arpa/inet.h>#include <fcntl.h>#include <pthread.h>#include <sys/time.h>#include <host.h>#include <http.h>#include <ants.h>#include <wait_read.h>#include <skip_lock.h>#include <config.h>	int get_http_size(struct mission *pms) {	signed long i;	int s, err = 0;	char cmd[256];	char msg_hdr[1024];	char *p;		sprintf(cmd, "GET %s HTTP/1.1\r\nHost: %s:%d\r\nReferer: %s\r\nConnection: close\r\n\r\n", pms->path, pms->host, pms->port, pms->referer);#ifdef DEBUG	printf("cmd line is \n%s.\n", cmd);#endif		for(i = 0; i < TIMES; i++) {			while(1) {			if((s = connect_host(pms->host, pms->port)) <= 0) sleep(1);			else{				break;			}			printf("connect host again.\n");		}		if(send(s, cmd, strlen(cmd), 0) != strlen(cmd)) {			printf("write error.\n");			err = 1;		}		else {				int state;#ifdef DEBUG			printf("writes ok\n");#endif			_wait_read(s, state, 20);	/*macro*/			if(state < 1) {				sleep(2);				continue;			}			if(recv(s, msg_hdr, 1024, 0) < 0) {				printf("read error.\n");				err = 1;			}			else				err = 0;		}		if(!(err))			break;		sleep(2);	}		if(err)		return 0;	#ifdef DEBUG	printf("size read ok\n");#endif		close(s);#ifdef DEBUG	i = find_start(msg_hdr, 1024);	msg_hdr[i - 2] = 0;	printf("%s", msg_hdr);#endif	i = (int)(strstr(msg_hdr, "200") - msg_hdr);	if( (i <= 0) || i > 20) {			/*add error handler code here.*/				return 0;	}		if((p = strstr(msg_hdr, "Content-Length")) || (p = strstr(msg_hdr, "Content-length:")))		p+= 16;	else {		p = msg_hdr;		while((p = strstr(p, "\r\n"))) {	/*fixup some file don't have string "Content-Length", I hope it works ok! */			p = p + 2;			if((*p <= '9') && (*p >= '0'))				break;		}		if(!p)			return 0;	}	s = atoi(p);	printf("Content-length: %d\n", s);	return s;	}		static void down_http_fragment(struct ants *ant) {	char cmd[256];	char data[PACKSIZE];	char *buffer_start;	char *buffer;	int s, fd, size, speed, offset, packsize;	int first, read, state, bytesleft;	struct mission *pms;		first = 1;	pms = ant->pms;	size = ant->buf_size;	buffer_start = malloc(size);		sprintf(cmd, "GET %s HTTP/1.1\r\nRange: bytes=%d-\r\nHost: %s:%d\r\nReferer: %s\r\n\r\n",pms->path, ant->position, pms->host, pms->port, pms->referer);		do {		while(1) {			if((s = connect_host(pms->host, pms->port)) <= 0)				sleep(1);			else{				ant->s = s;				break;			}			printf("connect host again.\n");		}			if(send(s, cmd, strlen(cmd), 0) != strlen(cmd)) {			close(s);			sleep(5);			continue;		}	} while (0);		chdir(pms->file_path);	fd = open(pms->file, O_WRONLY|O_CREAT, 0644);	retry:	offset = 0;	packsize = PACKSIZE;	buffer = buffer_start;	bytesleft = ant->end - ant->position + 1 ;	lseek(fd, ant->position, 0);		while(bytesleft) {		_wait_read(s, state, 30);	/*macro*/		if(state < 1){			sleep(2);			continue;		}			if(offset + packsize > size)			packsize = size - offset;		if(packsize > bytesleft)			packsize = bytesleft;			if(first) {			int start_text;			first = 0;				read = recv(s, data, packsize, MSG_WAITALL);			/*extract head of http connect*/			start_text = find_start(data, read);			if(start_text == -1) {				ant->ret = -1;				goto bad_head;			}			read -= start_text;			memcpy(buffer, data + start_text, read);		}		else {			read = recv(s, data, packsize, MSG_WAITALL);			memcpy(buffer, data, read);		}			buffer += read;		bytesleft -= read;		offset += read;		speed = -1; /*skip save buffer flag*/		if(bytesleft && ((offset + packsize) <= size))			continue;			write(fd, buffer_start, offset);		ant->position += offset;		if(!skip_lock(&pms->skip_lock)) {	/*save download state, if abort, we can continue*/			state_save(pms);			speed = statistic(ant);			skip_unlock(&pms->skip_lock);		}			if(bytesleft)			goto retry;		else			break;	}	ant->ret = 0;bad_head:	close(s);	close(fd);	free(buffer_start);#ifdef DEBUG	printf("thread %d exit.\n", ant->thread);#endif	pthread_exit(NULL);}		void down_http(struct mission *pms) {	int i, time, thread;	struct timeval now, last;	struct ants *ant;	char file[MAX_HOSTNAME];	pthread_t *pthread;	ant = pms->first_ant;	thread = pms->thread;	pthread = malloc(sizeof(pthread_t) * thread);	gettimeofday(&last, NULL);	for(i = 0; i < thread; i++) {		pthread_create(&pthread[i], NULL, (void *)down_http_fragment, (void *)&ant[i]);	}		for(i = 0; i < thread; i++) {		if(ant[i].ret == -1) {			printf("the %d thread error.\n", i);		}		pthread_join(pthread[i], NULL);	}	gettimeofday(&now, NULL);	time = (now.tv_sec - last.tv_sec) * 1000000 +(now.tv_usec - last.tv_usec);	time /= 1000;	printf("cost time %d.%d s\n", (time / 1000), (time / 10));	printf("100%% download\n");	free(pthread);	free(pms->first_ant);	close(pms->fd);	sprintf(file, "%s%s.nat",pms->file_path, pms->file);	del_file(file);}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -