a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 119|回复: 2

[C语言] 2011年计算机等级考试二级C辅导实例编程(18)

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
 用C语言开发FastCGI应用程序  I/O函数包
) g& ?0 D* w4 c) i. K6 c3 g* m  FastCGI软件开发套件,开源的WebServer 2.0服务器包含I/O函数包用与简化把已存在的CGI程序转成FastCGI程序或者编写FastCGI程序,在开发套件中有两个函数包:fcgi_stdio 和 fcgiapp,在你的程序中必须包含这些包中的一个:
: `6 i1 i9 F' G! A- K  fcgi_stdio.h
# @  v( \* Y5 S0 b* T4 L  fcgiapp.h
( r2 U1 N# i3 Y* r/ E9 M  fcgi_stdio包,是fcgiapp包的顶层包,在转化CGI程序或者是写新的FastCGI程序是,我们强烈推荐你用它,fcgi_stdio包有以下几个优点:$ U' |2 s( v  B
  简单:只要有三个性的API需要学。
1 M' y9 }- d. Q  易懂:如果你正包CGI程序转化为FastCGI程序,你会发现CGI程序与FastCGI程序之间只有很少的区别。在我们设计函数库的时候我们尽可能的 把FastCGI应用程序变得容易理解,以至于我们在建立新FastCGI程序的时候我们使用相同的环境变量,相同的解析查询字符串的技术,以及相同的 I/O程序等。
+ s- `  m  u1 L  方便:这个库函数提供了CGI和FastCGI二进制的文件的完美兼容。因此不管是CGI还是FastCGI,都同样运行。4 q) L8 L4 @  m5 @9 `+ a. f& ]3 e3 U
  代码结构# m3 y1 p  ~% B0 c6 j( |
  FastCGI的代码构成,把你的代码分成两个独立部分:
% a- s& `0 l; ?  1.初始化部分:只执行一次
0 a5 W4 I, E7 |/ u2 @" [$ j: g* G  2.应答循环部分:FastCGI脚本每被调用一次,这部分九被执行一次
# s3 Q1 A  o4 T+ u  一个应答循环的典型格式如下:
) x5 `1 C1 F4 N- z  K: Y; y. Y  while (FCGI_Accept() >= 0) {//循环条件
, r! k4 d4 t7 x1 X5 a8 H  # 应答循环体
% K* h: _' X8 G- C9 e) P5 s( e  }+ x5 g# T8 R* x! u# W, p5 i: t, j
  知道一个客户端请求来的时候FCGI_Accept块才执行,并返回0。如果有一个系统故障,或是系统管理员终止进程,Accept将返回-1。/ k# C# X+ r7 }- H: @
  如果应用程序作为一个CGI程序被调用,那么第一次调用Accept时,返回0,第二次总是返回-1,产生CGI行为。(请详见20页的"FCGI_Accept (3)" )3 i$ m1 y! P& V4 T
  注意,在CGI中鼓励用小脚本,然而在FastCGI中则鼓励使用组合式的脚本。你可以在从新构想你的程序的全局结构,来获得FastCGI的高性能。% C7 G& b/ D$ s0 z. J  ?: c' Z
  例1: TinyFastCGI
7 W5 w" E, U% J) w6 E: O4 j  这是一个用C语言写的一个简单FastCGI应答程序例子:
9 R: A% `4 J+ d; H1 B  #include "fcgi_stdio.h"$ Z: L* W; V* {; _3 i% [+ ~
  #include
( v5 w% _6 C. z, I! R7 k  int count;+ _3 h7 S+ X) f9 j& C
  void initialize(void)
& y  |  m, g: s5 q: C3 l/ }2 _  {
3 S7 d$ s6 L( X! \' k) P* X: N  count=0;, i, A. ]* T! A% t
  }: L5 d# r3 X: A1 I0 t
  void main(void)
回复

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:09 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(18)

  {
! v" [3 ~4 T! N  initialize();4 w3 u* a: c0 y# V+ d; U, P
  while (FCGI_Accept() >= 0) {
7 ^3 ]/ b2 X+ K' _5 g0 C  printf("Content-type: text/html\r\n"* ?: Z! g" a, O! |1 K" H
  "\r\n"5 R& }6 M6 e2 \4 b- c( |
  ""
& p! N3 K8 \3 C* o  "
5 b% n& u# {! W% @2 ?! D& j; }( ]+ d  FastCGI Hello! (C, fcgi_stdio library)8 A5 T4 q: T" A+ l5 O
  "( |! k, S! f4 P
  "Request number %d running on host %s\n",& S. {! W' }0 O$ `" A, J
  ++count, getenv("SERVER_HOSTNAME"));" y& c2 Z, g2 \' o1 z* p! v& |% I
  }
" T' V- m" b' _( ~# a  }8 d% t9 j& ?5 {, b) _: [1 X) ^: a
  例2:原始数据产生器* r7 X& Z! Q, b& Q
  思考一下,一个应答应用程序产生第N次原始数据。& o) @/ m/ F+ @8 \3 u
  一个CGI应用程序将没有有效的方法来解决这个问题。例如,如果用户访问第50000次的原始数据,那么CGI应用程序就不许从第一条原始数据开始计算,知道第50000条的,要是应用程序终止,伴随着她辛苦积累的数据也会随之消失。
; l$ B- J: a9 P2 Z  如果一个客户端想访问第4900条原始数据,那么服务器必须重新开始积累。
& B8 \6 }2 f# w- b& Z9 V  由于我们能维持这个状态,FastCGI应用程序对与这样的问题就更有效。一个FastCGI应用程序在初始化阶段能够计算一个扩展的源数据的表,并保持表的不同范围。当客户端请求一个特别原始数据的时候,循环应答需要从表里查询。
- P$ r6 W0 D3 i  S  这里有一个原始数据代码事例:5 E, i6 Z! S( D) M* W7 ^0 g" D- b
  #include "fcgi_stdio.h"2 O6 T# B) I) }% Y' `
  #include' I) ]6 a) {8 g9 J  c- B
  #include3 a  p/ _: B& `; @
  #define POTENTIALLY_PRIME 0
/ _; ?. m# F/ N. p1 }  #define COMPOSITE 1
+ \5 I) u+ s, S* p* B  #define VALS_IN_SIEVE_TABLE 1000000
" z1 U: l" Z  R; w  l  #define MAX_NUMBER_OF_PRIME_NUMBERS 78600
* n3 V" l7 T4 e- R3 k  long int sieve_table[VALS_IN_SIEVE_TABLE];: S8 G3 f5 H3 n  ~1 T" s& [2 a7 r
  long int prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];
9 ]! X+ j* v7 n& `, N  void& j2 ]7 i2 E5 D1 m  C2 T8 n
  initialize_prime_table(void)& T  U0 h3 P) z
  {1 S" Z% C  j3 ]1 G# i$ i
  long int prime_counter=1;" d* P1 g7 c( A7 K% c$ |
  long int current_prime=2, c, d;6 I( L$ J% i, V3 o6 P
  prime_table[prime_counter]=current_prime;! Y  V. }% ?% w6 Y5 i) B& l8 ]) N
  while (current_prime < VALS_IN_SIEVE_TABLE) {4 }* [8 C. _3 }0 g1 [# v3 ~/ y
  for (c = current_prime; c = 0) {
( P3 r, Q0 O. }7 k- w: [+ V  printf("Content-type: text/html\r\n"
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:10 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(18)

 "\r\n");  printf("\n"
/ e0 t" M) f4 k( N2 S  e  "
# p% s2 `! N1 v1 D  Prime FastCGI
& M' y3 E( b+ |  l+ p1 p0 c& d# k  \n");
* f) M* X. i: L  G  query_string = getenv("QUERY_STRING");
2 ]# Y( h) E' s( O  if(query_string == NULL) {
  A: l( \2 m) _  printf("Usage: Specify a positive number in the query string.\n");
9 c& R  a, c; n% J  } else {; y- L& C4 Q3 F
  query_string = strchr(query_string, `=') + 1;
+ y5 t2 u3 H% l7 u. t! J2 v  n = strtol(query_string);. L( B9 C5 ^) _/ g
  if(n < 1) {: n4 ]- G, T, }( [7 p
  printf("The query string `%s' is not a positive number.\n",
& E3 l6 k+ p$ S; T- H0 C9 F  query_string);
+ U: O# a' ]% k, j* S1 b# V  } else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {
4 T% E, n* X; Q" U  printf("The number %d is too large for this program.\n", n);9 s- w4 _9 f1 [# z# s
  } else{
( n1 r9 z5 f# O% G8 B5 G' s3 r/ q  printf("The %ldth prime number is %ld.\n", n, prime_table[n]);5 f+ v6 V! C2 C; b- a" V, V0 G' T
  }. t6 s) F$ k3 |- s9 S! u, k0 h. ^
  }
2 T$ M5 }( b3 x0 [" y, V, W  }
& q& W* x# Z. m  }
( F: ]# d# h# f% h4 H  这个应用程序在初始化时有一个显而意见的开销,但是后来的访问是快速的。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-22 13:36 , Processed in 0.268735 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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