请选择 进入手机版 | 继续访问电脑版

我爱学习网

 
查看: 11331|回复: 0

用C语言开发FastCGI应用程序

[复制链接]
发表于 2015-2-25 14:43:48 | 显示全部楼层 |阅读模式
本帖最后由 HelloWorld 于 2015-2-25 14:45 编辑

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应答程序例子:


  1. <font face="微软雅黑">#include "fcgi_stdio.h"
  2.   
  3.   #include <stdlib.h>
  4.   
  5.   int count;
  6.   
  7.   void initialize(void)
  8.   {
  9.   count=0;
  10.   }
  11.   
  12.   void main(void)
  13.   {
  14.   
  15.   initialize();
  16.   
  17.   
  18.   while (FCGI_Accept() >= 0) {
  19.   printf("Content-type: text/html\r\n"
  20.   "\r\n"
  21.   "<title>FastCGI Hello! (C, fcgi_stdio library)</title>"
  22.   "<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"
  23.   "Request number %d running on host <i>%s</i>\n",
  24.   ++count, getenv("SERVER_HOSTNAME"));
  25.   }
  26.   }</font>
复制代码

  例2:原始数据产生器

  思考一下,一个应答应用程序产生第N次原始数据。

  一个CGI应用程序将没有有效的方法来解决这个问题。例如,如果用户访问第50000次的原始数据,那么CGI应用程序就不许从第一条原始数据开始计算,知道第50000条的,要是应用程序终止,伴随着她辛苦积累的数据也会随之消失。

  如果一个客户端想访问第4900条原始数据,那么服务器必须重新开始积累。

  由于我们能维持这个状态,FastCGI应用程序对与这样的问题就更有效。一个FastCGI应用程序在初始化阶段能够计算一个扩展的源数据的表,并保持表的不同范围。当客户端请求一个特别原始数据的时候,循环应答需要从表里查询。

  这里有一个原始数据代码事例:

  1. <font face="微软雅黑">  #include "fcgi_stdio.h"
  2.   #include <stdlib.h>
  3.   #include <string.h>
  4.   
  5.   #define POTENTIALLY_PRIME 0
  6.   #define COMPOSITE 1
  7.   #define VALS_IN_SIEVE_TABLE 1000000
  8.   #define MAX_NUMBER_OF_PRIME_NUMBERS 78600
  9.   
  10.   
  11.   long int sieve_table[VALS_IN_SIEVE_TABLE];
  12.   long int prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];
  13.   
  14.   void
  15.   initialize_prime_table(void)
  16.   {
  17.   long int prime_counter=1;
  18.   long int current_prime=2, c, d;
  19.   
  20.   prime_table[prime_counter]=current_prime;
  21.   
  22.   while (current_prime < VALS_IN_SIEVE_TABLE) {
  23.   
  24.   for (c = current_prime; c <= VALS_IN_SIEVE_TABLE;
  25.   c += current_prime) {
  26.   sieve_table[c] = COMPOSITE;
  27.   }
  28.   
  29.   
  30.   for (d=current_prime+1; sieve_table[d] == COMPOSITE; d++);
  31.   
  32.   prime_table[++prime_counter]=d;
  33.   current_prime=d;
  34.   }
  35.   }
  36.   void main(void)
  37.   {
  38.   char *query_string;
  39.   long int n;
  40.   
  41.   initialize_prime_table();
  42.   
  43.   while(FCGI_Accept() >= 0) {
  44.   
  45.   printf("Content-type: text/html\r\n"
  46.   "\r\n");
  47.   
  48.   printf("<title>Prime FastCGI</title>\n"
  49.   "<h1>Prime FastCGI</h1>\n");
  50.   query_string = getenv("QUERY_STRING");
  51.   if(query_string == NULL) {
  52.   printf("Usage: Specify a positive number in the query string.\n");
  53.   } else {
  54.   query_string = strchr(query_string, `=') + 1;
  55.   n = strtol(query_string);
  56.   if(n < 1) {
  57.   printf("The query string `%s' is not a positive number.\n",
  58.   query_string);
  59.   } else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {
  60.   printf("The number %d is too large for this program.\n", n);
  61.   } else{
  62.   printf("The %ldth prime number is %ld.\n", n, prime_table[n]);
  63.   }
  64.   }
  65.   }
  66.   }</font>
复制代码

  这个应用程序在初始化时有一个显而意见的开销,但是后来的访问是快速的。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回列表 返回顶部