程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 用C語言開發FastCGI應用程序

用C語言開發FastCGI應用程序

編輯:關於C

FastCGI軟件開發套件,開源的WebServer 2.0服務器包含I/O函數包用與簡化把已存在的CGI程序轉成FastCGI程序或者編寫FastCGI程序

  I/O函數包

  FastCGI軟件開發套件,開源的WebServer 2.0服務器包含I/O函數包用與簡化把已存在的CGI程序轉成FastCGI程序或者編寫FastCGI程序,在開發套件中有兩個函數包:fcgi_stdio 和 fcgiapp,在你的程序中必須包含這些包中的一個:

  fcgi_stdio.h fcgiapp.h fcgi_stdio包,是fcgiapp包的頂層包,在轉化CGI程序或者是寫新的FastCGI程序是,我們強烈推薦你用它,fcgi_stdio包有以下幾個優點:

  簡單:只要有三個性的API需要學。

  易懂:如果你正包CGI程序轉化為FastCGI程序,你會發現CGI程序與FastCGI程序之間只有很少的區別。在我們設計函數庫的時候我們盡可能的 把FastCGI應用程序變得容易理解,以至於我們在建立新FastCGI程序的時候我們使用相同的環境變量,相同的解析查詢字符串的技術,以及相同的 I/O程序等。

  方便:這個庫函數提供了CGI和FastCGI二進制的文件的完美兼容。因此不管是CGI還是FastCGI,都同樣運行。

  代碼結構

  FastCGI的代碼構成,把你的代碼分成兩個獨立部分:

  1.初始化部分:只執行一次

  2.應答循環部分:FastCGI腳本每被調用一次,這部分九被執行一次

  

  一個應答循環的典型格式如下:

  while (FCGI_Accept() >= 0) {//循環條件

  

  # 應答循環體

  

  }

  

  知道一個客戶端請求來的時候FCGI_Accept塊才執行,並返回0。如果有一個系統故障,或是系統管理員終止進程,Accept將返回-1。

  如果應用程序作為一個CGI程序被調用,那麼第一次調用Accept時,返回0,第二次總是返回-1,產生CGI行為。(請詳見20頁的"FCGI_Accept (3)" )

  注意,在CGI中鼓勵用小腳本,然而在FastCGI中則鼓勵使用組合式的腳本。你可以在從新構想你的程序的全局結構,來獲得FastCGI的高性能。

  例1: TinyFastCGI

  這是一個用C語言寫的一個簡單FastCGI應答程序例子:

  #include "fcgi_stdio.h"

  

  #include <stdlib.h>

  

  int count;

  

  void initialize(void)

  {

  count=0;

  }

  

  void main(void)

  {

  

  initialize();

  

  

  while (FCGI_Accept() >= 0) {

  printf("Content-type: text/html\r\n"

  "\r\n"

  "<title>FastCGI Hello! (C, fcgi_stdio library)</title>"

  "<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"

  "Request number %d running on host <i>%s</i>\n",

  ++count, getenv("SERVER_HOSTNAME"));

  }

  }

  例2:原始數據產生器

  思考一下,一個應答應用程序產生第N次原始數據。

  一個CGI應用程序將沒有有效的方法來解決這個問題。例如,如果用戶訪問第50000次的原始數據,那麼CGI應用程序就不許從第一條原始數據開始計算,知道第50000條的,要是應用程序終止,伴隨著她辛苦積累的數據也會隨之消失。

  如果一個客戶端想訪問第4900條原始數據,那麼服務器必須重新開始積累。

  由於我們能維持這個狀態,FastCGI應用程序對與這樣的問題就更有效。一個FastCGI應用程序在初始化階段能夠計算一個擴展的源數據的表,並保持表的不同范圍。當客戶端請求一個特別原始數據的時候,循環應答需要從表裡查詢。

  這裡有一個原始數據代碼事例:

  #include "fcgi_stdio.h"

  #include <stdlib.h>

  #include <string.h>

  

  #define POTENTIALLY_PRIME 0

  #define COMPOSITE 1

  #define VALS_IN_SIEVE_TABLE 1000000

  #define MAX_NUMBER_OF_PRIME_NUMBERS 78600

  

  

  long int sieve_table[VALS_IN_SIEVE_TABLE];

  long int prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];

  

  void

  initialize_prime_table(void)

  {

  long int prime_counter=1;

  long int current_prime=2, c, d;

  

  prime_table[prime_counter]=current_prime;

  

  while (current_prime < VALS_IN_SIEVE_TABLE) {

  

  for (c = current_prime; c <= VALS_IN_SIEVE_TABLE;

  c += current_prime) {

  sieve_table[c] = COMPOSITE;

  }

  

  

  for (d=current_prime+1; sieve_table[d] == COMPOSITE; d++);

  

  prime_table[++prime_counter]=d;

  current_prime=d;

  }

  }

  void main(void)

  {

  char *query_string;

  long int n;

  

  initialize_prime_table();

  

  while(FCGI_Accept() >= 0) {

  

  printf("Content-type: text/html\r\n"

  "\r\n");

  

  printf("<title>Prime FastCGI</title>\n"

  "<h1>Prime FastCGI</h1>\n");

  query_string = getenv("QUERY_STRING");

  if(query_string == NULL) {

  printf("Usage: Specify a positive number in the query string.\n");

  } else {

  query_string = strchr(query_string, `=') + 1;

  n = strtol(query_string);

  if(n < 1) {

  printf("The query string `%s' is not a positive number.\n",

  query_string);

  } else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {

  printf("The number %d is too large for this program.\n", n);

  } else{

  printf("The %ldth prime number is %ld.\n", n, prime_table[n]);

  }

  }

  }

  }

  這個應用程序在初始化時有一個顯而意見的開銷,但是後來的訪問是快速的。

*
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved