• <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 閱讀(1489) 評論(0)  編輯 收藏 引用 所屬分類: Network
            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(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久久香蕉国产 | 亚洲欧美日韩精品久久亚洲区| 久久―日本道色综合久久| 久久久久一区二区三区| 国产精品VIDEOSSEX久久发布| 久久久久国产日韩精品网站| 人妻无码久久精品| 国产午夜免费高清久久影院 | 久久久国产视频| 99精品国产在热久久无毒不卡| 国产午夜电影久久| 亚洲精品乱码久久久久久久久久久久| 国产精品免费福利久久| 国内精品久久国产| 精品久久久久一区二区三区| 婷婷伊人久久大香线蕉AV| 久久精品亚洲男人的天堂| 久久精品国产清高在天天线| 久久青青草原精品国产软件 | 精品久久人人爽天天玩人人妻| 久久最近最新中文字幕大全| 亚洲精品美女久久久久99| 思思久久好好热精品国产| 国产午夜福利精品久久| 国产精品视频久久| 亚洲AV乱码久久精品蜜桃| 亚洲午夜福利精品久久| 国内精品伊人久久久久网站| 国产精品久久影院| 久久久久99精品成人片直播| 2021国内久久精品| 亚洲国产成人久久精品99 | 国内精品久久久久久久亚洲| 精品久久久久久久无码| 久久久无码精品亚洲日韩按摩| 超级碰碰碰碰97久久久久| 久久久国产一区二区三区| 爱做久久久久久| 很黄很污的网站久久mimi色| 99久久综合国产精品二区| 国产精品99久久久久久www|