1. 程式人生 > >http協議C語言程式設計實現

http協議C語言程式設計實現

轉載:http://zhoulifa.bokee.com/4640913.html

大家都很熟悉HTTP協議的應用,因為每天都在網路上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟體下載網頁,當用到那個“用FlashGet下載全部連結”時總覺得很神奇。

後來想想,其實要實現這些下載功能也並不難,只要按照HTTP協議傳送request,然後對接收到的資料進行分析,如果頁面上還有href之類的連結指向標誌就可以進行深一層的下載了。HTTP協議目前用的最多的是1.1版本,要全面透徹地搞懂它就參考RFC2616文件吧。
下面是我用C語言程式設計寫的一個http下載程式,希望對大家有些啟發。原始碼如下:


/******* 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=tolower(*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;
}

/*********************************************************************
*filename: httpclient.c
*purpose: HTTP協議客戶端程式,可以用來下載網頁
*wrote by: zhoulifa([email protected]) 周立發(http://zhoulifa.bokee.com)
           Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
*date time:2006-03-11 21:49:00
*Note: 任何人可以任意複製程式碼並運用這些程式碼,當然包括你的商業用途
*                         但請遵循GPL
*********************************************************************/
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);
}
//////////////////////////////httpclient.c 結束///////////////////////////////////////////

相關推薦

http協議C語言程式設計實現

轉載:http://zhoulifa.bokee.com/4640913.html 大家都很熟悉HTTP協議的應用,因為每天都在網路上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟體下載網頁,當用到那個“用FlashGet下載全部連

HTTP協議C語言程式設計實現例項

大家都很熟悉HTTP協議的應用,因為每天都在網路上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟體下載網頁,當用到那個“用FlashGet下載全部連結”時總覺得很神奇。 後來想想,其實要實現這些下載功能也並不難,只要按照HTTP協

詳解!C語言程式設計實現小遊戲“三子棋”

今天我們來程式設計實現一個充滿童趣的小遊戲“三子棋” 先來說一下三子棋的規則: 三子棋又叫九宮棋、圈圈叉叉、一條龍等。 將正方形對角線連起來,或相對兩邊依次擺上三個雙方棋子, 總之只要將自己的三個棋子走成一條線, 對方就算輸了。 不用再過多解釋了,相信大家一定都玩過! 那麼,該

課上補做:用C語言程式設計實現ls命令

課上補做:用C語言程式設計實現ls命令 一、有關ls ls :用來列印當前目錄或者制定目錄的清單,顯示出檔案的一些資訊等。 ls -l:列出長資料串,包括檔案的屬性和許可權等資料 ls -R:連同子目錄一同顯示出來,也就所說該目錄下所有檔案都會顯示出來 ls -a:可以將目錄下的全部檔案

計算位數最高達300位的兩個非負整數的乘積,C語言程式設計實現

-------世界太蕪雜,我幫你整理---- -------C語言大數相乘運算---------- 今天我們要程式設計實現的是兩個超長整型資料進行相乘,並輸出結果 比如: 2134897427972647678 * 3497892374 我們先來看看執行效果

離散數學真值表(c語言程式設計實現

程式碼如下: 廢話不多說: 主要利用二進位制的轉化實現  #include <iostream> #include <math.h> using namespace std; void shuru(char *p,int s); void shu

KST-51微控制器:c語言程式設計實現數碼管動態顯示秒錶的倒計時

/*60S倒計時*/ /*個位每1S變一次,從0~9*/ /*十位,個位為0的下一秒十位發生變化*/ #include<reg52.h> sbit ADDR0=P1^0; sbit ADDR1=P1^1; sbit ADDR2=P1^2; sbit ADDR3

Hanoi塔問題 棧與遞迴C語言程式設計實現

Hanoi塔 棧與遞迴C程式設計實現 參考書 嚴蔚敏  資料結構 #include <stdio.h> #include <stdlib.h> #include <conio.h> typedef int ElemType; type

C語言程式設計實現建立多個目錄(資料夾)

    因為要建立90個資料夾,本人實在不想一個一個的建立,就想是不是可以用C語言程式設計來實現呢,剛才查閱了很多部落格,終於終於我實現了,可以用迴圈的方式建立了,也不屬於自己原創,參考了很多大神的程式碼。現在我把原始碼貼出來,在Visual studio 2015上跑成功了

C語言程式設計實現使用AES對檔案進行加密

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>int main(int argc,char* argv[]){ 

c語言程式設計實現簡單三子棋遊戲

   分別建立test.c   game.c 兩個原始檔,以及game.h標頭檔案   這裡的三子棋遊戲是指棋盤為3*3,玩家與電腦之間的對決,先將各自的棋下為一排(橫/豎/斜)者獲勝,電腦所    下位置是隨機產生   1. game.h中用於函式定義,如下: #ifn

安信可-A7模組——C語言程式設計實現GPS功能

上一篇博文整理學習了有關串列埠通訊、串列埠程式設計的一些基本知識。本篇將通過程式設計來獲取、解析、轉換GPS接收機接收的資訊。 我們將在fl2440開發板上實現該功能。 一、A7與開發板連線 我使用的是USB轉TTL串列埠轉接線,這裡要保證Linux支

將兩個非遞減的有序連結串列合併為一個非遞增的有序連結串列(C語言程式設計實現

將兩個非遞減的有序連結串列合併為一個非遞增的有序連結串列。要求結果連結串列仍使用原來兩個連結串列的儲存空間, 不另外佔用其它的儲存空間。表中允許有重複的資料。 #include<stdio.

C語言程式設計實現,浮點型與字元陣列相互轉化

歡迎轉載,請註明出處,本文地址:http://blog.csdn.net/jk050802/article/details/8628764 聯絡郵箱:[email protected] 簡介          從浮點型轉換為字元型:這裡比較簡單,只需要用

c語言程式設計實現電腦com口發資料

#include <stdio.h>   #include <windows.h> #include   <stdlib.h> #include <string.h>   #include <conio.h>  

Java併發(十八):阻塞佇列BlockingQueue BlockingQueue(阻塞佇列)詳解 二叉堆(一)之 圖文解析 和 C語言實現 多執行緒程式設計:阻塞、併發佇列的使用總結 Java併發程式設計:阻塞佇列 java阻塞佇列 BlockingQueue(阻塞佇列)詳解

阻塞佇列(BlockingQueue)是一個支援兩個附加操作的佇列。 這兩個附加的操作是:在佇列為空時,獲取元素的執行緒會等待佇列變為非空。當佇列滿時,儲存元素的執行緒會等待佇列可用。 阻塞佇列常用於生產者和消費者的場景,生產者是往佇列裡新增元素的執行緒,消費者是從佇列裡拿元素的執行緒。阻塞佇列就是生產者

**c++基於tcp協議的socket程式設計實現一個簡單伺服器**

c++基於tcp協議的socket程式設計實現一個簡單伺服器 基於tcp的通訊,可以利益socket套接字實現。通訊,顧名思義需要伺服器和客戶端兩者進行資訊互動。 通過流程圖我們可以看到程式設計實現伺服器和客戶端的步驟大致相同,而伺服器則更為複雜一些。本文之給出了一個簡單的伺服器程式設計和

C語言程式設計基礎— 一維陣列 (程式設計實現從鍵盤輸入20個整數,統計非負數個數,並計算非負數之和。)

程式設計基礎—一維陣列 (程式設計實現從鍵盤輸入20個整數,統計非負數個數,並計算非負數之和。) #include<stdio.h> int main() { int a[20] ; int k=0,sum=0,i; for (i=0;i<20

linux下C語言程式設計日誌(1):基於TCP協議的伺服器/客戶端程式

  基於TCP協議的伺服器/客戶端程式  首先我們看一下使用TCP協議進行網路通訊的程式基本模型:伺服器首先進行初始化操作:呼叫函式socket建立一個套接字,函式bind將這個套接字與伺服器的公認地址繫結在一起,函式listen將這個套接字換成傾聽套接字,然後呼叫函式acc

Linux下的C語言程式設計——系統呼叫read和write函式實現檔案拷貝

 系統呼叫read和write函式實現檔案拷貝 #include <stdio.h> #include <sys/types.h> #include <sys/st