织梦CMS - 轻松建站从此开始!

罗索

HTTP Download Files Using Socket

落鹤生 发布于 2011-02-15 18:50 点击:次 
HTTP相关协议及说明,并包括一个HTTP client的Download Files 示例代码(Using Socket API)
TAG:

Http RFC

http 1.0 http://www.faqs.org/rfcs/rfc1945.html
http 1.1 http://www.faqs.org/rfcs/rfc2616.html
Http Request
Common
Http Request Headers
<Request> <File-Path> <Http-Version>\r\n
<Host>\r\n
<Other-Http-Headers>\r\n
<Content-Length>\r\n
\r\n
<Contents>
Comments
<Request>
Can be 'GET' and 'POST', 'GET' means to download file, while 'POST' means to upload file.
<File-Path>
The file path to be downloaded or uploaded
<Http-Version>
Can be 'HTTP/1.0' or 'HTTP/1.1'
<Host>
Can be 'Host: <server>", here <server> is the host name of server, such as www.xxx.com
<Content-Length>
Can be 'Content-Length: <number>', <number> is the size of contents that will be sent to server

xxx
Http Response
Common Http Response Headers
<Http-Version> <Status-Code> <Reason-Phrase> \r\n
<Content-Encoding> \r\n
<Content-Length> \r\n
<Other-Headers> \r\n
\r\n
<Contents>

xxx

Samples

  1. /******* http客户端程序 httpclient.c ******/ 
  2. #include <stdio.h> 
  3. #include <stdlib.h> 
  4. #include <string.h> 
  5. #include <sys/types.h> 
  6. #include <sys/socket.h> 
  7. #include <errno.h> 
  8. #include <unistd.h> 
  9. #include <netinet/in.h> 
  10. #include <limits.h> 
  11. #include <netdb.h> 
  12. #include <arpa/inet.h> 
  13. #include <ctype.h> 
  14.  
  15. //httpclient.c 开始// 
  16. /******************************************** 
  17. 功能:搜索字符串右边起的第一个匹配字符 
  18. ********************************************/ 
  19. char * Rstrchr(char * s, char x) { 
  20.   int i = strlen(s); 
  21.   if(!(*s)) return 0; 
  22.   while(s[i-1]) if(strchr(s + (i - 1), x)) return (s + (i - 1)); else i--; 
  23.   return 0; 
  24.  
  25. /******************************************** 
  26. 功能:把字符串转换为全小写 
  27. ********************************************/ 
  28. void ToLowerCase(char * s) { 
  29.   while(s && *s) {*s=tolower(*s);s++;} 
  30.  
  31. /******************************* 
  32. 功能:从字符串src中分析出网站地址和端口,并得到用户要下载的文件 
  33. *******************************/ 
  34. void GetHost(char * src, char * web, char * file, int * port) { 
  35.   char * pA; 
  36.   char * pB; 
  37.   memset(web, 0, sizeof(web)); 
  38.   memset(file, 0, sizeof(file)); 
  39.   *port = 0; 
  40.   if(!(*src)) return
  41.   pA = src; 
  42.   if(!strncmp(pA, "http://", strlen("http://"))) pA = src+strlen("http://"); 
  43.   else if(!strncmp(pA, "https://", strlen("https://"))) pA = src+strlen("https://"); 
  44.   pB = strchr(pA, '/'); 
  45.   if(pB) { 
  46.     memcpy(web, pA, strlen(pA) - strlen(pB)); 
  47.     if(pB+1) { 
  48.       memcpy(file, pB + 1, strlen(pB) - 1); 
  49.       file[strlen(pB) - 1] = 0; 
  50.     } 
  51.   } 
  52.   else memcpy(web, pA, strlen(pA)); 
  53.   if(pB) web[strlen(pA) - strlen(pB)] = 0; 
  54.   else web[strlen(pA)] = 0; 
  55.   pA = strchr(web, ':'); 
  56.   if(pA) *port = atoi(pA + 1); 
  57.   else *port = 80; 
  58.  
  59.  
  60. int main(int argc, char *argv[]) 
  61.   int sockfd; 
  62.   char buffer[1024]; 
  63.   struct sockaddr_in server_addr; 
  64.   struct hostent *host; 
  65.   int portnumber,nbytes; 
  66.   char host_addr[256]; 
  67.   char host_file[1024]; 
  68.   char local_file[256]; 
  69.   FILE * fp; 
  70.   char request[1024]; 
  71.   int send, totalsend; 
  72.   int i; 
  73.   char * pt; 
  74.  
  75.   if(argc!=2) 
  76.   { 
  77.     fprintf(stderr,"Usage:%s web-address\a\n",argv[0]); 
  78.     exit(1); 
  79.   } 
  80.   printf("parameter.1 is: %s\n", argv[1]); 
  81.   ToLowerCase(argv[1]);/*将参数转换为全小写*/ 
  82.   printf("lowercase parameter.1 is: %s\n", argv[1]); 
  83.  
  84.   GetHost(argv[1], host_addr, host_file, &portnumber);/*分析网址、端口、文件名等*/ 
  85.   printf("webhost:%s\n", host_addr); 
  86.   printf("hostfile:%s\n", host_file); 
  87.   printf("portnumber:%d\n\n", portnumber); 
  88.  
  89.   if((host=gethostbyname(host_addr))==NULL)/*取得主机IP地址*/ 
  90.   { 
  91.     fprintf(stderr,"Gethostname error, %s\n", strerror(errno)); 
  92.     exit(1); 
  93.   } 
  94.  
  95.   /* 客户程序开始建立 sockfd描述符 */ 
  96.   if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)/*建立SOCKET连接*/ 
  97.   { 
  98.     fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); 
  99.     exit(1); 
  100.   } 
  101.  
  102.   /* 客户程序填充服务端的资料 */ 
  103.   bzero(&server_addr,sizeof(server_addr)); 
  104.   server_addr.sin_family=AF_INET; 
  105.   server_addr.sin_port=htons(portnumber); 
  106.   server_addr.sin_addr=*((struct in_addr *)host->h_addr); 
  107.  
  108.   /* 客户程序发起连接请求 */ 
  109.   if(connect(sockfd,(struct sockaddr *)(&server_addr)
  110. ,sizeof(struct sockaddr))==-1)/*连接网站*/ 
  111.   { 
  112.     fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); 
  113.     exit(1); 
  114.   } 
  115.  
  116.   sprintf(request, "GET /%s HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\n\ 
  117. User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n\ 
  118. Host: %s:%d\r\nConnection: Close\r\n\r\n", host_file, host_addr, portnumber); 
  119.   printf("%s", request);/*准备request,将要发送给主机*/ 
  120.  
  121.   /*取得真实的文件名*/ 
  122.   if(host_file && *host_file) pt = Rstrchr(host_file, '/'); 
  123.   else pt = 0; 
  124.  
  125.   memset(local_file, 0, sizeof(local_file)); 
  126.   if(pt && *pt) { 
  127.     if((pt + 1) && *(pt+1)) strcpy(local_file, pt + 1); 
  128.     else memcpy(local_file, host_file, strlen(host_file) - 1); 
  129.   } 
  130.   else if(host_file && *host_file) strcpy(local_file, host_file); 
  131.   else strcpy(local_file, "index.html"); 
  132.   printf("local filename to write:%s\n\n", local_file); 
  133.  
  134.   /*发送http请求request*/ 
  135.   send = 0;totalsend = 0; 
  136.   nbytes=strlen(request); 
  137.   while(totalsend < nbytes) { 
  138.     send = write(sockfd, request + totalsend, nbytes - totalsend); 
  139.     if(send==-1) {printf("send error!%s\n", strerror(errno));exit(0);} 
  140.     totalsend+=send; 
  141.     printf("%d bytes send OK!\n", totalsend); 
  142.   } 
  143.  
  144.   fp = fopen(local_file, "a"); 
  145.   if(!fp) { 
  146.     printf("create file error! %s\n", strerror(errno)); 
  147.     return 0; 
  148.   } 
  149.   printf("\nThe following is the response header:\n"); 
  150.   i=0; 
  151.   /* 连接成功了,接收http响应,response */ 
  152.   while((nbytes=read(sockfd,buffer,1))==1) 
  153.   { 
  154.     if(i < 4) { 
  155.       if(buffer[0] == '\r' || buffer[0] == '\n') i++; 
  156.       else i = 0; 
  157.       printf("%c", buffer[0]);/*把http头信息打印在屏幕上*/ 
  158.     } 
  159.     else { 
  160.       fwrite(buffer, 1, 1, fp);/*将http主体信息写入文件*/ 
  161.       i++; 
  162.       if(i%1024 == 0) fflush(fp);/*每1K时存盘一次*/ 
  163.     } 
  164.   } 
  165.   fclose(fp); 
  166.   /* 结束通讯 */ 
  167.   close(sockfd); 
  168.   exit(0); 

zj@zj:~/C_pram/practice/http_client$ ls
httpclient httpclient.c
zj@zj:~/C_pram/practice/http_client$ ./httpclient http://www.baidu.com/

parameter.1 is: http://www.baidu.com/

lowercase parameter.1 is: http://www.baidu.com/

webhost:www.baidu.com
hostfile:
portnumber:80

GET / HTTP/1.1
Accept: *
 
原文地址 http://blog.chinaunix.net/u2/76292/showart_1353805.html

(websurf)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201102/10890.html]
本文出处:websurf.cublog.cn  作者:websurf
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容