winsock之前不认识,现在也未深知。
机缘:需要下载48张图片,它们的HTTP地址是连续的,于是想到程序。
蓝本:寻自互联网角落,经改变而成。 部分注释是私见,可能不准确。
功能:url_gen.txt中存放需要下载的HTTP地址,文件下载至文件夹Downloads下;尝试过.mp3,.jpg,.html。
编程语言:C
编译环境:gcc。
代码:
#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <dir.h>
//#pragma comment(lib, "ws2_32.lib")
//上一行是VC加载库的写法,GCC编译为加参数:-lws2_32
//winsock2.h对应库ws2_32.lib,winsock.h对应库wsock32.lib,但该处即使交叉对应也没出问题,不知何解。
int download(char *url, char *dir)
{
WSADATA WSAData={0};
SOCKET sockfd;
struct sockaddr_in addr;
struct hostent *pURL;
char temp_url[256];
char *url_cursor;// For getting host and GET
char host[256], GET[256];
char temp_dir[256];
char *file_name;
char request[256];
static char text[BUFSIZ];
int test_len;
char *resp_header;
FILE *fn;
int i=0;
//windows下使用socket必须用WSAStartup初始化,否则不能调用
if(WSAStartup(MAKEWORD(2,2), &WSAData))
{
printf("WSA failed\n");
return -1;
}
//分离url中的主机地址和相对路径
strcpy(temp_url, url);
for (url_cursor = temp_url; *url_cursor != '/' && *url_cursor != '\0'; url_cursor++);
if ( !*url_cursor)
strcpy(GET, "/");
else
{
strcpy(GET, url_cursor);
*url_cursor = '\0';
}
strcpy(host, temp_url);
printf("%s\n%s\n", GET, host);
//分离url中的文件名
strcpy(temp_dir, dir);
for(file_name = url + strlen(url) -1;*file_name != '/' && file_name != url; file_name--);
if (*file_name == '/')
file_name ++;
else
file_name = url;
strcat(temp_dir, "\\");
strcat(temp_dir, file_name);
file_name = temp_dir;
// printf("FILE_NAME: %s\n", file_name);
//设定socket参数,并未真正初始化
sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
pURL = gethostbyname(host);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = *((unsigned long*)pURL->h_addr);
addr.sin_port = htons(80);
//组织发送到web服务器的信息
//为何要发送下面的信息请参考HTTP协议的约定
strcpy(request, "GET ");
strcat(request, GET);
strcat(request, " HTTP/1.1\r\n");
strcat(request, "HOST: ");
strcat(request, host);
strcat(request, "\r\nConnection: Close\r\n\r\n");
//连接到服务器,发送访问请求
if(connect(sockfd,(SOCKADDR *)&addr,sizeof(addr))!=0)
{ //连接超时
return -1;
}
send(sockfd, request, strlen(request), 0);
printf("REQUEST:%s\n", request);
//接收响应,剥离响应头部,存储文件
test_len = recv(sockfd, text, BUFSIZ, 0);
printf("RESPONSE:%s\n", text);
fn = fopen(file_name,"wb");
resp_header = strstr(text, "close");
resp_header+=9;
i = resp_header - text;
fwrite(text+i,sizeof(char),test_len-i,fn);
// fwrite(text, sizeof(char), test_len, fn);
strnset(text, '\0', BUFSIZ);
while ( (test_len=recv(sockfd, text, BUFSIZ, 0)) > 0)
{
fwrite(text, sizeof(char), test_len, fn);
strnset(text, '\0', BUFSIZ);
}
fclose(fn);
closesocket(sockfd);
WSACleanup();
return i;
}
int main()
{
char url[256]="music1.fjnet.com/attachment/MP3/20100129/20100129115740_123.mp3";
char dir[]="Downloads";
FILE *fn;
fn = fopen("url_gen.txt", "r");
mkdir(dir);
while(fscanf(fn, "%s", url) != EOF)
{
download(url, dir);
printf("OVER: %s\n", url);
}
fclose(fn);
return 0;
}