• <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

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            99国产精品久久久久久久成人热| 久久99国产一区二区三区| 一本色道久久88—综合亚洲精品| 久久AV无码精品人妻糸列| 久久亚洲私人国产精品| 久久精品国产一区| 一日本道伊人久久综合影| 无码人妻久久一区二区三区免费| 999久久久免费精品国产| 久久天天躁狠狠躁夜夜av浪潮| 99久久精品免费看国产一区二区三区| 日韩人妻无码精品久久久不卡 | 亚洲精品NV久久久久久久久久| 无码人妻久久一区二区三区蜜桃| 久久国产精品一国产精品金尊 | 久久久久99精品成人片三人毛片 | 久久久久久夜精品精品免费啦| 色综合久久中文综合网| 久久综合亚洲鲁鲁五月天| 香港aa三级久久三级| 久久亚洲欧美国产精品 | 亚洲精品无码久久久久sm| 成人精品一区二区久久| 久久久一本精品99久久精品88| 模特私拍国产精品久久| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久精品黄AA片一区二区三区| 婷婷久久精品国产| 久久久久久久国产免费看| 国产精品一区二区久久国产| 亚洲日韩中文无码久久| 中文字幕久久亚洲一区| 久久无码国产| 日批日出水久久亚洲精品tv| 91久久精品无码一区二区毛片| 国产91久久精品一区二区| 嫩草伊人久久精品少妇AV| 亚洲精品国产美女久久久| 亚洲日本va午夜中文字幕久久 | 中文无码久久精品| 中文字幕无码精品亚洲资源网久久|