• <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 閱讀(1493) 評論(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

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久中文字幕| 一本色道久久88综合日韩精品| 一级做a爰片久久毛片看看| 人妻少妇精品久久| 99久久无码一区人妻a黑| 精品乱码久久久久久夜夜嗨| 国内精品伊人久久久影院| 国产精品久久久久久久| 日韩久久无码免费毛片软件| 成人妇女免费播放久久久| 日韩亚洲国产综合久久久| 成人资源影音先锋久久资源网| 久久人人爽人人爽AV片| 久久99精品久久久久久hb无码 | 欧美日韩成人精品久久久免费看| 热久久视久久精品18| 99久久国产免费福利| 久久青青草原精品国产| 日本精品一区二区久久久| 国产2021久久精品| 新狼窝色AV性久久久久久| 一本色道久久88综合日韩精品| 久久精品国产亚洲一区二区| 久久精品人人做人人爽电影| 久久久久国色AV免费看图片| 国产精品久久久久aaaa| 久久人爽人人爽人人片AV| 久久人人爽人人人人片av| 久久久这里只有精品加勒比| 精品无码久久久久久国产| 91超碰碰碰碰久久久久久综合| 久久99精品久久久久久hb无码| 久久精品国产色蜜蜜麻豆| 久久一区二区三区免费| 久久久久99精品成人片牛牛影视| 国产精品青草久久久久婷婷 | 亚洲国产精品久久久久网站| 久久久无码人妻精品无码| 久久精品人人做人人爽97 | 亚洲国产视频久久| 中文字幕乱码久久午夜|