c语言实现http文件下载,C语言winsock实现HTTP下载

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

#include

#include

#include

#include

#include //header

#pragma comment (lib, "ws2_32.lib") //lib

#define MAXSIZE 1024

void GET(char *url, char *host, char *file_name)

{

int length = 0;

char *url_end = (char *)(url + strlen(url));

char *host_begin, *host_end, *file;

/* 查找主机的开始位置 */

host_begin = strstr(url, "//") +2; //判断//是否是url的子串。如果是,则该函数返回//在url中首次出现的地址

host_end = strchr(host_begin, '/'); //查找字符串begin中首次出现:的位置

if (host_end == NULL)

{

host_end = url_end;

}

else

{ /* 得到文件名 */

file = strrchr(host_end, '/'); //返回指定字符最后一次出现位置的地址

if (file && (file + 1) != url_end)

strcpy(file_name, file + 1);

}

/* 得到主机信息 */

length = host_end - host_begin;

memcpy(host, host_begin, length);

host[length] = 0;

}

int main()

{

WSADATA wsa;

SOCKET sk;

sockaddr_in addr;

hostent * remoteHost;

FILE *fp;

char header[MAXSIZE],host[MAXSIZE],file_name[MAXSIZE];

char *http_req_hdr_tmpl = "GET %s HTTP/1.1\r\n"

"Accept: image/gif, image/jpeg, */*\r\nAccept-Language: zh-cn\r\n"

"Accept-Encoding: gzip, deflate\r\nHost: %s:%d\r\n"

"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36\r\n"

"Connection: keep-alive\r\n\r\n";

char url[MAXSIZE];

int send_len,result;

scanf("%s",url); //输入URL

GET(url, host, file_name);

if( WSAStartup(MAKEWORD(1,1), &wsa) ){

printf("初始化失败!!!");

return 1;

}

if( (remoteHost = gethostbyname(host)) == NULL )

{

printf("通过主机名获取地址失败!!!");

return 1;

}

sk=socket(AF_INET,SOCK_STREAM,0);

if(sk==SOCKET_ERROR){

printf("设置socket错误!!!");

return 1;

}

//设置主机地址

addr.sin_family = AF_INET;

addr.sin_port = htons(80);

addr.sin_addr.s_addr = *((unsigned long *)*remoteHost->h_addr_list); //转换地址

if( connect(sk, (const sockaddr * )&addr, sizeof(addr)) )

{

printf("连接失败!!!");

closesocket(sk);

return 1;

}

//要发送的http头部

send_len = sprintf(header, http_req_hdr_tmpl, url, host, 80);

result = send(sk, header, send_len, 0);

if (result == SOCKET_ERROR) /* 发送失败 */

{

printf("发送失败!!! error = %d\n", WSAGetLastError());

return -1;

}

char path[MAXSIZE]={"C:/Users/Administrator/Desktop/"},buf[MAXSIZE],wbuf[MAXSIZE];

strcat(path,file_name);

fp=fopen(path, "w+");

bool done = FALSE;

int l,chars=0;

//打印并保存http响应的头部

while(!done)

{

l = recv(sk,buf,1,0);

if(l<0)

done=TRUE;

switch(*buf)

{

case '\r':

break;

case '\n':

if(chars==0)

done = TRUE;

chars=0;

break;

default:

chars++;

break;

}

printf("%c",*buf);

}

//接收正文部分

int sum = 0;

do{

l = recv(sk,buf,MAXSIZE-1,0);

if( l < 0 )

break;

sum += l;

*(buf + l) = 0;

fputs(buf,fp);

}while( l > 0 );

fflush(fp);

fclose(fp);

closesocket(sk);

WSACleanup();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Windows 平台上,可以使用 Winsock 库来实现 HTTP 下载文件。以下是一个简单的 C 语言程序,演示如何实现 HTTP 下载文件: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #define BUFFER_SIZE 1024 int main(int argc, char *argv[]) { if (argc < 2) { printf("usage: %s url\n", argv[0]); return 1; } // 初始化 Winsock 库 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { perror("WSAStartup failed"); return 1; } // 解析 URL char *url = argv[1]; char *host = strtok(url, "/"); char *path = strtok(NULL, ""); if (path == NULL) { path = "/"; } // 建立 TCP 连接 struct hostent *server = gethostbyname(host); if (server == NULL) { perror("gethostbyname failed"); return 1; } SOCKET sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockfd == INVALID_SOCKET) { perror("socket failed"); return 1; } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(80); memcpy(&addr.sin_addr.s_addr, server->h_addr, server->h_length); if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) { perror("connect failed"); return 1; } // 发送 HTTP 请求 char request[BUFFER_SIZE]; sprintf(request, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", path, host); if (send(sockfd, request, strlen(request), 0) == SOCKET_ERROR) { perror("send failed"); return 1; } // 接收 HTTP 响应 char response[BUFFER_SIZE]; int n = recv(sockfd, response, BUFFER_SIZE, 0); if (n == SOCKET_ERROR) { perror("recv failed"); return 1; } response[n] = '\0'; // 解析响应头 char *content_length = strstr(response, "Content-Length:"); if (content_length == NULL) { printf("unknown file size\n"); return 1; } int file_size = atoi(content_length + strlen("Content-Length:")); printf("file size: %d\n", file_size); // 写入文件 FILE *file = fopen("file.txt", "wb"); char buffer[BUFFER_SIZE]; int total = 0; while (total < file_size) { n = recv(sockfd, buffer, BUFFER_SIZE, 0); if (n == SOCKET_ERROR) { perror("recv failed"); return 1; } fwrite(buffer, sizeof(char), n, file); total += n; } fclose(file); // 关闭连接 closesocket(sockfd); // 卸载 Winsock 库 WSACleanup(); printf("file downloaded\n"); return 0; } ``` 注意:以上代码仅供参考,实际使用时需要添加错误处理和其他必要的检查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值