• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0

            大家都很熟悉HTTP協議的應用,因為每天都在網絡上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用 thunder之類的下載軟件下載網頁,當用到那個“用thunder下載全部鏈接”時總覺得很神奇。
            后來想想,其實要實現這些下載功能也并不難,只要按照HTTP協議發送request,然后對接收到的數據進行分析,如果頁面上還有href之類的鏈接指 向標志就可以進行深一層的下載了。HTTP協議目前用的最多的是1.1 版本,要全面透徹地搞懂它就參考RFC2616文檔吧。我是怕rfc文檔了的,要看自己去看吧^_^
            源代碼如下:
            /******* http客戶端程序 httpclient.c ************/
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <sys/types.h>
            #include <sys/socket.h>
            #include <errno.h>
            #include <unistd.h>
            #include <netinet/in.h>
            #include <limits.h>
            #include <netdb.h>
            #include <arpa/inet.h>
            #include <ctype.h>

            //////////////////////////////httpclient.c 開始///////////////////////////////////////////


            /********************************************
            功能:搜索字符串右邊起的第一個匹配字符
            ********************************************/
            char * Rstrchr(char * s, char x) {
              int i = strlen(s);
              if(!(*s)) return 0;
              while(s[i-1]) if(strchr(s + (i - 1), x)) return (s + (i - 1)); else i--;
              return 0;
            }

            /********************************************
            功能:把字符串轉換為全小寫
            ********************************************/
            void ToLowerCase(char * s) {
              while(s && *s) {*s=tolower(*s);s++;}
            }

            /**************************************************************
            功能:從字符串src中分析出網站地址和端口,并得到用戶要下載的文件
            ***************************************************************/
            void GetHost(char * src, char * web, char * file, int * port) {
              char * pA;
              char * pB;
              memset(web, 0, sizeof(web));
              memset(file, 0, sizeof(file));
              *port = 0;
              if(!(*src)) return;
              pA = src;
              if(!strncmp(pA, "http://", strlen("http://"))) pA = src+strlen("http://");
              else if(!strncmp(pA, "https://", strlen("https://"))) pA = src+strlen("https://");
              pB = strchr(pA, '/');
              if(pB) {
                memcpy(web, pA, strlen(pA) - strlen(pB));
                if(pB+1) {
                  memcpy(file, pB + 1, strlen(pB) - 1);
                  file[strlen(pB) - 1] = 0;
                }
              }
              else memcpy(web, pA, strlen(pA));
              if(pB) web[strlen(pA) - strlen(pB)] = 0;
              else web[strlen(pA)] = 0;
              pA = strchr(web, ':');
              if(pA) *port = atoi(pA + 1);
              else *port = 80;
            }


            int main(int argc, char *argv[])
            {
              int sockfd;
              char buffer[1024];
              struct sockaddr_in server_addr;
              struct hostent *host;
              int portnumber,nbytes;
              char host_addr[256];
              char host_file[1024];
              char local_file[256];
              FILE * fp;
              char request[1024];
              int send, totalsend;
              int i;
              char * pt;

              if(argc!=2)
              {
                fprintf(stderr,"Usage:%s web-address\a\n",argv[0]);
                exit(1);
              }
              printf("parameter.1 is: %s\n", argv[1]);
              ToLowerCase(argv[1]);/*將參數轉換為全小寫*/
              printf("lowercase parameter.1 is: %s\n", argv[1]);

              GetHost(argv[1], host_addr, host_file, &portnumber);/*分析網址、端口、文件名等*/
              printf("webhost:%s\n", host_addr);
              printf("hostfile:%s\n", host_file);
              printf("portnumber:%d\n\n", portnumber);

              if((host=gethostbyname(host_addr))==NULL)/*取得主機IP地址*/
              {
                fprintf(stderr,"Gethostname error, %s\n", strerror(errno));
                exit(1);
              }

              /* 客戶程序開始建立 sockfd描述符 */
              if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)/*建立SOCKET連接*/
              {
                fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
                exit(1);
              }

              /* 客戶程序填充服務端的資料 */
              bzero(&server_addr,sizeof(server_addr));
              server_addr.sin_family=AF_INET;
              server_addr.sin_port=htons(portnumber);
              server_addr.sin_addr=*((struct in_addr *)host->h_addr);

              /* 客戶程序發起連接請求 */
              if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)/*連接網站*/
              {
                fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
                exit(1);
              }

              sprintf(request, "GET /%s HTTP/1.1\r\nAccept: */*\r\nAccept-Language: zh-cn\r\n\
            User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\r\n\
            Host: %s:%d\r\nConnection: Close\r\n\r\n", host_file, host_addr, portnumber);
              printf("%s", request);/*準備request,將要發送給主機*/

              /*取得真實的文件名*/
              if(host_file && *host_file) pt = Rstrchr(host_file, '/');
              else pt = 0;

              memset(local_file, 0, sizeof(local_file));
              if(pt && *pt) {
                if((pt + 1) && *(pt+1)) strcpy(local_file, pt + 1);
                else memcpy(local_file, host_file, strlen(host_file) - 1);
              }
              else if(host_file && *host_file) strcpy(local_file, host_file);
              else strcpy(local_file, "index.html");
              printf("local filename to write:%s\n\n", local_file);

              /*發送http請求request*/
              send = 0;totalsend = 0;
              nbytes=strlen(request);
              while(totalsend < nbytes) {
                send = write(sockfd, request + totalsend, nbytes - totalsend);
                if(send==-1) {printf("send error!%s\n", strerror(errno));exit(0);}
                totalsend+=send;
                printf("%d bytes send OK!\n", totalsend);
              }

              fp = fopen(local_file, "a");
              if(!fp) {
                printf("create file error! %s\n", strerror(errno));
                return 0;
              }
              printf("\nThe following is the response header:\n");
              i=0;
              /* 連接成功了,接收http響應,response */
              while((nbytes=read(sockfd,buffer,1))==1)
              {
                if(i < 4) {
                  if(buffer[0] == '\r' || buffer[0] == '\n') i++;
                  else i = 0;
                  printf("%c", buffer[0]);/*把http頭信息打印在屏幕上*/
                }
                else {
                  fwrite(buffer, 1, 1, fp);/*將http主體信息寫入文件*/
                  i++;
                  if(i%1024 == 0) fflush(fp);/*每1K時存盤一次*/
                }
              }
              fclose(fp);
              /* 結束通訊 */
              close(sockfd);
              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: */*
            Accept-Language: zh-cn
            User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
            Host: www.baidu.com:80
            Connection: Close

            local filename to write:index.html

            163 bytes send OK!

            The following is the response header:
            HTTP/1.1 200 OK
            Date: Wed, 29 Oct 2008 10:41:40 GMT
            Server: BWS/1.0
            Content-Length: 4216
            Content-Type: text/html
            Cache-Control: private
            Expires: Wed, 29 Oct 2008 10:41:40 GMT
            Set-Cookie: BAIDUID=A93059C8DDF7F1BC47C10CAF9779030E:FG=1; expires=Wed, 29-Oct-38 10:41:40 GMT; path=/; domain=.baidu.com
            P3P: CP=" OTI DSP COR IVA OUR IND COM "

            zj@zj:~/C_pram/practice/http_client$ ls
            httpclient  httpclient.c  index.html

            不指定文件名字的話,默認就是下載網站默認的首頁了^_^.

            from:
            http://blog.chinaunix.net/u2/76292/showart_1353805.html

            posted on 2010-06-27 23:16 chatler 閱讀(1490) 評論(0)  編輯 收藏 引用 所屬分類: Network
            <2010年1月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品中文字幕第23页| 2020久久精品国产免费| 久久精品国产亚洲综合色| 久久综合综合久久综合| 久久精品国产亚洲AV影院| 精品久久久无码人妻中文字幕| 久久天天躁夜夜躁狠狠| 一本色道久久综合狠狠躁| 久久精品人成免费| 久久香蕉一级毛片| 天天做夜夜做久久做狠狠| 久久婷婷五月综合成人D啪| 成人妇女免费播放久久久| 久久精品国产一区二区三区不卡 | 久久久久人妻一区二区三区vr| 亚洲综合熟女久久久30p| 精品国产VA久久久久久久冰| 亚洲国产成人久久综合一| 久久有码中文字幕| 97久久久精品综合88久久| 欧美激情精品久久久久久久| av无码久久久久不卡免费网站| 色婷婷久久久SWAG精品| 一本一道久久精品综合| 99蜜桃臀久久久欧美精品网站 | 国产免费久久精品99久久| 无码精品久久一区二区三区| 精品久久久久久久久中文字幕| 欧美国产精品久久高清| 91久久香蕉国产熟女线看| 久久婷婷五月综合色奶水99啪| 伊人色综合九久久天天蜜桃| 欧美亚洲另类久久综合| 国产情侣久久久久aⅴ免费| 久久久久久久97| 日韩AV毛片精品久久久| 精品久久久久久久中文字幕| 久久久久国产精品| 青青热久久综合网伊人| 久久精品国产99国产精偷| 精品国产乱码久久久久久郑州公司|