• <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 閱讀(1491) 評論(0)  編輯 收藏 引用 所屬分類: Network
            <2010年6月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            常用鏈接

            留言簿(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久久| 国产人久久人人人人爽| 成人精品一区二区久久久| 久久精品九九亚洲精品天堂| 精品久久久久久久久中文字幕| 国产女人aaa级久久久级| 久久国产视屏| 久久综合精品国产二区无码| 色综合久久久久网| 亚洲国产视频久久| 久久久久久综合一区中文字幕| 激情久久久久久久久久| 亚洲精品tv久久久久久久久| 久久精品国内一区二区三区| 欧美日韩精品久久免费| 一本色道久久88加勒比—综合| 人人狠狠综合88综合久久| 国产精品久久久久AV福利动漫| 亚洲国产综合久久天堂 | 久久久这里有精品| 97久久精品午夜一区二区| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久九九免费高清视频| 天堂久久天堂AV色综合| 欧美麻豆久久久久久中文| 久久精品国内一区二区三区| 99精品久久久久久久婷婷| 久久精品一区二区影院| 国产日韩久久免费影院| 国产精品内射久久久久欢欢| 久久国产高潮流白浆免费观看| 久久精品中文字幕一区| 色天使久久综合网天天| 久久久久婷婷| 久久精品国产99国产精品| 99热都是精品久久久久久| 狠狠色丁香婷婷久久综合不卡| 久久久久久久久无码精品亚洲日韩| 久久久久免费精品国产| 亚洲国产精品无码久久98| 日韩精品久久无码人妻中文字幕|