a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 120|回复: 2

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

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
 用C语言开发FastCGI应用程序  I/O函数包
8 c/ V0 z  p; X! t% e, L  FastCGI软件开发套件,开源的WebServer 2.0服务器包含I/O函数包用与简化把已存在的CGI程序转成FastCGI程序或者编写FastCGI程序,在开发套件中有两个函数包:fcgi_stdio 和 fcgiapp,在你的程序中必须包含这些包中的一个:
& ~2 ^+ q1 z8 E3 {  @  fcgi_stdio.h4 e  `4 j- q7 Y/ I6 l9 c/ J8 Q
  fcgiapp.h2 B( b5 K& T% A/ ]- z& Y
  fcgi_stdio包,是fcgiapp包的顶层包,在转化CGI程序或者是写新的FastCGI程序是,我们强烈推荐你用它,fcgi_stdio包有以下几个优点:$ H/ V0 m% ?5 z# i9 o/ `
  简单:只要有三个性的API需要学。% w6 |9 P$ h4 g8 x0 ]0 [$ K8 C
  易懂:如果你正包CGI程序转化为FastCGI程序,你会发现CGI程序与FastCGI程序之间只有很少的区别。在我们设计函数库的时候我们尽可能的 把FastCGI应用程序变得容易理解,以至于我们在建立新FastCGI程序的时候我们使用相同的环境变量,相同的解析查询字符串的技术,以及相同的 I/O程序等。! R& }5 H3 ^. ^, P4 a/ M
  方便:这个库函数提供了CGI和FastCGI二进制的文件的完美兼容。因此不管是CGI还是FastCGI,都同样运行。
7 M; B- W' f& D8 K  代码结构
  P1 h( W4 l+ F# i  FastCGI的代码构成,把你的代码分成两个独立部分:( s( F/ J$ {) d* u5 @
  1.初始化部分:只执行一次% I  F" A+ ?- H) W
  2.应答循环部分:FastCGI脚本每被调用一次,这部分九被执行一次
$ O& R2 v) p/ ?& m  一个应答循环的典型格式如下:& I6 j# O- X3 G" U9 A7 S; ^; _/ O
  while (FCGI_Accept() >= 0) {//循环条件
$ p9 Y4 m  t6 N8 g. z6 j) O  t' w, m  # 应答循环体
$ z8 g  |' M) a- l3 s+ ~4 g8 g  }" }- W, l. t+ f4 N3 H) }) u
  知道一个客户端请求来的时候FCGI_Accept块才执行,并返回0。如果有一个系统故障,或是系统管理员终止进程,Accept将返回-1。
" s' I* d  s/ N4 J+ y8 U  如果应用程序作为一个CGI程序被调用,那么第一次调用Accept时,返回0,第二次总是返回-1,产生CGI行为。(请详见20页的"FCGI_Accept (3)" )% S2 T8 w8 l) y$ K. Y; V$ E
  注意,在CGI中鼓励用小脚本,然而在FastCGI中则鼓励使用组合式的脚本。你可以在从新构想你的程序的全局结构,来获得FastCGI的高性能。
* c- q3 y/ N! d! M' J  例1: TinyFastCGI
4 ~* |. V0 C+ Y6 x2 o1 |  这是一个用C语言写的一个简单FastCGI应答程序例子:  w$ E3 h$ A8 @
  #include "fcgi_stdio.h"; B" T0 k- G5 Z3 p9 s" r) O0 {+ l) |
  #include# {' E2 a% \7 |+ P+ }
  int count;
# C/ j1 |, W, h# l7 M  void initialize(void)
; i9 ^. R8 y& \% R9 i( O( V  {7 m" n9 \  u. ~4 Q% v1 p
  count=0;; Y% F& ]0 K; l6 f2 ]0 C9 f
  }, k; M- ^6 P# g( h( B2 N7 ]" \
  void main(void)
回复

使用道具 举报

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

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

  {1 g! x6 L. g1 W1 \) {
  initialize();
/ D% R2 q3 U: B5 h8 i  while (FCGI_Accept() >= 0) {# f; M( n) ?+ S+ |& Y) ^
  printf("Content-type: text/html\r\n"
& y9 L4 w" O1 ]% \$ L3 j2 Z* m  "\r\n"" @5 m4 z8 T8 {0 T# x% K9 L' ~; r+ v
  ""
0 d/ y' S+ Z- p2 M! w9 I  "
, M7 ^! w5 P2 D- ~7 B+ [& S  FastCGI Hello! (C, fcgi_stdio library)
% k4 v. U/ U* m; A  "
5 H5 O# Q/ a9 N! @  "Request number %d running on host %s\n",+ E& x, d: z- T, q
  ++count, getenv("SERVER_HOSTNAME"));5 Z: J3 }: T1 @, b5 J8 l
  }( y5 V, a( z) w- H* n- G9 y+ {  U
  }$ H5 n+ u6 A( G* d
  例2:原始数据产生器
6 I4 y8 Y7 F! {& [" h  思考一下,一个应答应用程序产生第N次原始数据。# ?# l2 S9 \7 \! R" b4 Z
  一个CGI应用程序将没有有效的方法来解决这个问题。例如,如果用户访问第50000次的原始数据,那么CGI应用程序就不许从第一条原始数据开始计算,知道第50000条的,要是应用程序终止,伴随着她辛苦积累的数据也会随之消失。
8 g, ?' ]: T- y, m2 [  如果一个客户端想访问第4900条原始数据,那么服务器必须重新开始积累。
! C; ?* p4 ^! N+ w  由于我们能维持这个状态,FastCGI应用程序对与这样的问题就更有效。一个FastCGI应用程序在初始化阶段能够计算一个扩展的源数据的表,并保持表的不同范围。当客户端请求一个特别原始数据的时候,循环应答需要从表里查询。
, J: l# T: m& W9 S3 `7 E3 R* g4 w  这里有一个原始数据代码事例:; y+ W$ n4 L* G* ^! Z' }# Z
  #include "fcgi_stdio.h"
# ^! @  l" |7 S- A4 q+ O  #include
: o4 m( U2 @1 q1 Y; X  #include* i. Y' F/ w* a) F1 q3 F8 H+ ?
  #define POTENTIALLY_PRIME 0
% Y1 C( I/ x6 n  #define COMPOSITE 1
1 l! f7 I8 v- t# d+ n% f  #define VALS_IN_SIEVE_TABLE 1000000$ E) M! `0 Z" O8 X( M% N
  #define MAX_NUMBER_OF_PRIME_NUMBERS 78600# H: d$ s7 s) o, V
  long int sieve_table[VALS_IN_SIEVE_TABLE];
2 E5 M' ^7 b4 h* q+ G! A  long int prime_table[MAX_NUMBER_OF_PRIME_NUMBERS];
* ^" r) _5 z% L1 m  void+ ]# k: ^& N/ I# t2 T
  initialize_prime_table(void)
3 O; G) z; r" s5 {% O1 R! K! \2 e1 n  {; d2 u4 B; c: A% A
  long int prime_counter=1;' t/ P  m* |) _) D7 j  j5 b/ o
  long int current_prime=2, c, d;
6 l9 G8 ]) O9 R  prime_table[prime_counter]=current_prime;% o4 ]; H3 {- p7 F+ F7 h5 G/ l6 s
  while (current_prime < VALS_IN_SIEVE_TABLE) {3 m- B2 t  K/ f
  for (c = current_prime; c = 0) {; w6 j% j% t+ o" X( _& c/ i6 z
  printf("Content-type: text/html\r\n"
回复 支持 反对

使用道具 举报

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

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

 "\r\n");  printf("\n"
- S+ }+ u8 W4 i* L7 f. z  "% ]. b1 y, h: _/ N% ~  ?
  Prime FastCGI; o3 }) t' Z) W3 \2 @4 ]
  \n");" j) U/ m( p3 a
  query_string = getenv("QUERY_STRING");* O! L* H! E* S$ N4 s2 }
  if(query_string == NULL) {' A2 u5 x2 Q, n3 D" [
  printf("Usage: Specify a positive number in the query string.\n");/ {1 ]  [- O4 Y9 z6 g  J6 N
  } else {) Z0 W, ^& A7 Y
  query_string = strchr(query_string, `=') + 1;8 `4 l* ^6 R4 A; |2 P$ I$ W; p9 P
  n = strtol(query_string);$ n2 |) H1 Y& M- u2 V9 G
  if(n < 1) {' a0 M8 r! n7 Z  i
  printf("The query string `%s' is not a positive number.\n",
, W0 |3 r9 q( O2 E  query_string);
! s6 H, n$ R% ]+ @6 Z5 f! T+ w/ }  } else if(n > MAX_NUMBER_OF_PRIME_NUMBERS) {2 d* z+ C! B" @2 E
  printf("The number %d is too large for this program.\n", n);; T  Q7 T  C% \& R5 Q
  } else{  L9 Y7 p& A1 I/ M6 U/ Y5 h7 b7 l
  printf("The %ldth prime number is %ld.\n", n, prime_table[n]);
3 `) U9 F( k& [5 ~; K. e  }
: V5 z) B* G' x7 H  @! Y! ^  }
& q' J2 d2 K5 W6 }1 W* b% [& E  }
. l6 `1 f/ B& P. D" b, W' ^  }) [' v* |3 b/ Q
  这个应用程序在初始化时有一个显而意见的开销,但是后来的访问是快速的。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-16 16:14 , Processed in 0.281390 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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