公共网关接口Common Gateway Interface

作者在 2009-03-06 13:43:16 发布以下内容
CGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。
  Common Gate Interface听起来让人有些专业, 我们就管它叫CGI好了。在物理上,CGI是一段程序,它运行在Server上,提供同客户端 Html页面的接口。这样说大概还不好理解。那么我们看一个实际例子: 现在的个人主页上大部分都有一个留言本。留言本的工作是这样的:先由用户在客户端输入一些信息,如名字之类的东西。接着用户按一下“留言”(到目前为止工作都在客户端),浏览器把这些信息传送到服务器的CGI目录下特定的cgi程序中,于是cgi程序在服务器上按照预定的方法进行处理。在本例中就是把用户提交的信息存入指定的文件中。然后cgi程序给客户端发送一个信息,表示请求的任务已经结束。此时用户在浏览器里将看到“留言结束”的字样。整个过程结束。
  》 电影中的CGI技术指
  computer generated image电脑生成的画面

2. 功能:

  绝大多数的CGI程序被用来解释处理来自表单的输入信息,并在服务器产生相应的处理,或将相应的信息反馈给浏览器。CGI程序使网页具有交互功能。

3. 运行环境:

  CGI程序最初在UNIX操作系统上CERN或NCSA格式的服务器上运行。
  在其它操作系统(如:windows NT及windows95等)的服务器上也广泛地使用CGI程序,同时它也适用于各种类型机器。

4. CGI处理步骤:

  ⑴通过Internet把用户请求送到服务器。
  ⑵服务器接收用户请求并交给CGI程序处理。
  ⑶CGI程序把处理结果传送给服务器。
  ⑷服务器把结果送回到用户。

5. CGI服务器配置:

  CGI程序不是放在服务器上就能顺利运行,如果要想使其在服务器上顺利的运行并准确的处理用户的请求,则须对所使用的服务器进行必要的设置。
  配置:根据所使用的服务器类型以及它的设置把CGI程序放在某一特定的目录中或使其带有特定的扩展名。
  ⑴CREN格式服务器的配置:
  编辑CREN格式服务器的配置文件(通常为/etc/httpd.conf)
  在文件中加入:Exec cgi-bin/*/home/www/cgi-bin/*.exec命令中出现的第一个参数cgi-bin/*指出了在URL中出现的目录名字,并表示它出现在系统主机后的第一个目录中,如:http://edgar.stern.nyn.edu/cgi-bin/
  命令中的第二个参数表示CGI程序目录放在系统中的真实路径。
  CGI目录除了可以点网络文件放在同一目录中,也可以放在系统的其它目录中,但必须保证在你的系统中也具有同样的目录。在对服务器完成设置后,须重新启动服务器(除非HTTP服务器是用inetd启动的)。
  ⑵NCSA格式服务器的配置
  在NCSA格式服务器上有两种方法进行设置:
  ①在srm.conf文件(通常在conf目录下)中加入:Script Alias/cgi-bin/cgi-bin/
  Script Alias命令指出某一目录下的文件是可执行程序,且这个命令是用来执行这些程序的;此命令的两个参数与CERN格式服务器中的Exec命令的参数的含意一样。
  ②在srm.conf文件加入:Add type application/x-httpd-cgi.cgi
  此命令表示在服务器上增加了一种新的文件类型,其后第一个参数为CGI程序的MIME类型,第二个参数是文件的扩展名,表示以这一扩展名为扩展名的文件是CGI程序。
  在用上述方法之一设置服务器后,都得重新启动服务器(除非HTTP服务器是用inetd启动的)。

6. CGI的编写语言

  CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。对初学者来说,最好选用易于归档和能有效表示大量数据结构的语言,例如UNIX环境中:
  · Perl (Practical Extraction and Report Language)
  · Bourne Shed或者Tcl (Tool Command Language)
  由于C语言有较强的平台无关性,所以也是编写CGI程序的首选。
  Windows环境中:
  · C和C++
  由于Internet上大部分服务器使用的是UNIX操作系统,且几乎任一UNIX操作系统中都有Bourne Shell,因而后面讲述的例子中大部分是用Bourne Shell编写的。
  最终Perl由于其跨操作系统、易于修改的特性成为了CGI的主流编写语言,以至于一般的“cgi程序”就是Perl程序。

7. CGI环境变量列表

  SERVER-NAME:运行CGI序为机器名或IP地址。
  SEUVER-INTERFACE:WWW服务器的类型,如:CERN型或NCSA型。
  SERVER-PROTOCOL:通信协议,应当是HTTP/1.0。
  SERVER-PORT:TCP端口,一般说来web端口是80。
  HTTP-ACCEPT:HTTP定义的浏览器能够接受的数据类型。
  HTTP-REFERER: 发送表单的文件URL。(并非所有的浏览器都传送这一变量)
  HTTP-USER-AGENT:发送表单的浏览器的有关信息。
  GETWAY-INTERFACE:CGI程序的版本,在UNIX下为 CGI/1.1。
  PATH-TRANSLATED: PATH-INFO中包含的实际路径名。
  PATH-INFO:浏览器用GET方式发送数据时的附加路径。
  SCRIPT-NAME: CGI程序的路径名。
  QUERY-STRING:表单输入的数据,URL中间号后的内容。
  REMOTE-NOST:发送程序的主机名,不能确定该值。
  REMOTE-ADDR:发送程序的机器的IP地址。
  REMOTE-USBR:发送程序的人名。
  CONTENT-TYPE:POST发送,一般为applioation/xwww-form-urlencoded。
  CONTENT-LENGTH:POST方法输入的数据的字节数。

8.为什么使用CGI?

  CGI可以为我们提供许多HTML无法做到的功能。比如 a.一个记数器 b.顾客信息表格的提交以及统计 c.搜索程d.WEB数据库,用Html是没有办法记住客户的任何信息的,就算用户愿意让你知道。用Html也是无法把信息记录到某一个特定文件里的。要把客户段的信息记录在服务器的硬盘上,就要用到CGI。 这是CGI最重要的作用,它补充了Html的不足。是的,仅仅是补充,不是替代。

补充:

  CGI(Computer Generation Image)三次元CG
  CGI(Computer Graphics Interface)计算机图形接口
  发动机CGI技术是一种奔驰公司开发的缸内直喷技术。供油动作已完全独立于进门与活塞系统之外,ECU也因而拥有更多的主导权。超乎传统喷射理论的稀薄燃烧与更多元的混合比便得以实现。在稳定行进或低负载状态下,采用缸内直喷设计的发动机得以进入Ultra lean(精实)模式。在此设定下,发动机于进气行程时只能吸进空气,至于喷油嘴则在压缩行程才供给燃料,以达到节约的效果。根据实际测试,其最高能达到1:65的油、气比例,除了节能表现相当惊人,整体动力曲线也能够维持相当高的平顺度。然而本模式由于会产生相当大量的NOx(硫化物)与高温,所幸由于技术与材料科学的突破,也已得到了解决。
  CGI:Common Gateway Interface
  CGI代表Common Gateway Interface(通用网关界面),它使在网络服务器下运行外部分应用程序(或网关)成为可能。CGI-BIN 目录是存放CGI脚本的地方。这些脚本使WWW服务器和浏览器能运行外部程序,而无需启动另一个原因程序。
  它是运行在Web服务器上的一个程序,并由来自于浏览者的输人触发。CGI是在HTTP服务器下运行外部程序(或网关)的一个接口,它能让网络用户访问远程系统上的使用类型程序,就好像他们在实际使用那些远程计算机一样。
  CGI能够让浏览者与服务器进行交互,如果你曾经遇到过在网络上填表或者进行搜索,就很有可能就是用的CGI。
  尽管CGI易于使用,但是当大批人同时使用一个CGI应用程序是会反应较慢,网络服务器 速度也会受到很大 影响。CGI应用程序的优点是可以独立运行。
  CGI应用程序可以由大多数的编程语言编写,如Perl(Practical Extraction and Report Language)、C\C++、Java 和Visual Basic等。不过对于那些没有太多编程经验的网页制作人来说,实在是一个不小的难题。
  CGI应用程序的工作原理是这样的:
  1.浏览器通过HTML表单或超链接请求指上一个CGI应用程序的URL。
  2.服务器收发到请求。
  3.服务器执行指定所CGI应用程序。
  4.CGI应用程序执行所需要的操作,通常是基于浏览者输人的内容。
  5.CGI应用程序把结果格式化为网络服务器和浏览器能够理解的文档(通常是HTML网页)。
  6.网络服务器把结果返回到浏览器中。
  有关CGI应用程序要注意的是:
  CGI应用程序运行在浏览器可以请求的服务器系统上,执行时需要使用服务器CPU时间和内存。如果有成千上万的这种程序会同时运行,那会对服务器系统提出极高的要求。你要慎重考虑这个问题,以防止服务器系统崩溃。
  不完善的CGI应用程序可能成为别人非法进人服务器系统的通道,有可能导致重要的资料被删除或外泄。
  CGI应用程序主要的用途有以下几种:
  根据浏览者填写的HTML表单发送定制的答复。
  创建可单击的图像缩小图。
  创建一个浏览者可以搜索内容的数据库。
  提供服务器与数据库的接口,并把结果转换成HTML文档。
  制作动态HTML文挡。
  如果一个CGI脚本可以在每台计算机上做同样的事情;编写脚本就会变的很容易。不幸的是,CGI脚本依赖于服务器的操作系统,因此,对于非UNIX服务器来说,Prl(UNIX下编写脚本的一个常用工具)脚本毫无用处。所以,你必须定制安装你的CGI脚本。
  大多数服务器都提供CGI-BIN目录,但是这还不够。因为你应该拥有自己的CGI-BIN。这样,你就能运行自己的脚本(而不是让自己的系统去适应已存在于系统上的脚本)。因此,你的提供商应安装CGI-BIN,且能够帮助你编写脚本
  二、ASP:Active Server Pages
  ASP,活动服务器页面,就是一个编程环境,在其中,可以混合使用HTML、脚本语言以及组件来创建服务器端功能强大的Internet应用程序。 如果你以前创建过一个站点,其中混合了HTML、脚本语言以及组件,你就可以在其中加入ASP程序代码。通过在HTML页面中加入脚本命令,你可以创建一个HTML用户界面,并且,还可以通过使用组件包含一些商业逻辑规则。组件可以被脚本程序调用,也可以由其他的组件调用。
  ASP的工作原理:
  当在Web站点中融入ASP功能后,将发生以下事情:
  1、用户调出站点内容,默认页面的扩展名是.asp。
  2、浏览器从服务器上请求ASP文件。
  3、服务器端脚本开始运行ASP。
  4、ASP文件按照从上到下的顺序开始处理,执行脚本命令,执行HTML页面内容。
  5、页面信息发送到浏览器。
  因为脚本是在服务器端运行的,所以Web服务器完成所有处理后,将标准的HTML页面送往浏览器。这意味着,ASP只能在可以支持的服务器上运行。让脚本驻留在服务器端的另外一个益处是:用户不可能看到原始脚本程序的代码,用户看到的,仅仅是最终产生的HTML内容
  三、PHP:Personal Home Page
  PHP 是一种服务器端的,嵌入HTML的脚本语言。PHP区别其他像客户端Javascript的地方是它的代码在服务器端执行.PHP能做什么?
  最低水平,PHP可以做任何其他CGI程序所能做的事,例如收集表格数据,生成动态页面内容,或者收发cookies.可能最强大,最有意义的特性是PHP支持大范围的数据库.书写一个支持数据库的Web 页面是难以置信的简单.
  下面是当前支持的数据库:
  Adabas D InterBase Solid
  dBase mSQL Sybase
  Empress MySQL Velocis
  FilePro Oracle Unix dbm
  Informix PostgreSQL
  PHP通过协议也支持与其他服务的"交谈",像IMAP, SNMP, NNTP, POP3, 甚至是 HTTP. 你也可以打开晦涩的 网络接口和其他协议交互.
  PHP的简要历史
  1994年秋季, Rasmus Lerdorf 开始构思 PHP. 早期的非发行版本被用在他的主页上,以追踪谁在看他的在线简历. 1995年年初第一版本出台,当时PHP只被认为是个人主页开发工具.它由一个非常单纯的只能理解很少数特殊宏的分析引擎和 一些用在主页后端通用的工具组成.如留言簿,计数器和其他一些东西.这个分析器在1995年年中被重写并被命名为 PHP/FI 第二版. FI来自 Rasmus 写的另外一个包, 用于解释 html 形式的数据.他结合了个人主页工具脚本和形式解析器,并加 上mSQL支持.这样就产生 PHP/FI 了. PHP/FI以令人惊奇的步调成长,人们开始把自己的代码贡献给它.
  很难给出它的硬统计表,但可以估计在1996年末,整个世界至少有15,000个网站在用PHP/FI.到1997年年中,这个 数字已经超过50,000了. 而在此时PHP的发展也发生了变化.由Rasmus自己偏爱的和几个人开发的项目变成一个更有组织的团 体成就.Zeev Suraski和Andi Gutmans重写了解析器.这个新的解析器成为PHP版本3的基础.许多有用的代码从PHP/FI 继承到PHP3,并且很多是完全重写的.
  今天(1999年年中)不管是PHP/FI或PHP3与很多商业产品捆绑在一块,例如C2级强度的Web服务器和红帽子Linux. 根据NetCraft提供的数据推断,保守估计全世界应用PHP的网站已超过150,000个.由此看来,它比在因特网上运行Netscape 的旗舰企业服务器的站点还多.
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  全球小区识别码CGI(Cell Global Identitier)
  ① 全球小区识别码(CGI)是用来识别一个小区(基站/一个扇形小区)所覆盖的区域
  ② CGI是在LAI的基础上再加小区识别码(CI)构成的
  ③ 其结构是
  MCC+MNC+LAC+CI
  MCC:移动国家码
  MNC:移动网络码
  LAC:位置区号码
  CI:小区标识码
  其中MCC\MNC\LAC为位置区标识(LAI)
  其中CI为2Byte的BCD码,由各MSC自定
技术 | 阅读 7980 次
文章评论,共4条
vfdff(作者)
2009-03-06 13:47
1
联网调试CGI程序心得初学用PERL写CGI程序,也找了个PERL的调试器PERL DEBUGGER来用,但好象对中文WINDOWS支持有问题,代码区总是一片混乱,一气之下就直接上网调试,一番头破血流下来,也积累了一些心得,写出来供跟我一样正在学习PERL的CGI编程的朋友们参考。<br />
CGI程序最常见的错误就是500 Internal Server Error,对于这个错误提示,可以按以下步骤查找原因。<br />
<br />
一、检查CGI程序的属性,一定要设为755才可以。<br />
<br />
二、检查一下是不是用了BINARY方式上传,CGI程序一定要用ASCII方式上传。建议在所用的FTP软件里把.cgi,.pl都设定为使用ASCII方式,并且把连接选项里的上传方式设为AUTO。<br />
<br />
三、如果上面两项都没有问题,那就是程序本身有语法问题,常见的语法问题有以下一些:<br />
1。没有指定perl解释器的位置,程序的第一行必须是服务器上PERL解释器的位置,一般是#!/usr/bin/perl<br />
2。在输出前没有先输出一个http头CGI程序必须告诉浏览器,这以后的输出将作为一个HTML文档来对待,建议将这个语句作为一个函数,在输出前调用之,下面是一个例子。<br />
sub Head {<br />
print “Content-type: text/htmlnn”;<br />
}<br />
3。某语句少写了分号<br />
4。括号、引号等不配套,常见的是少写一边,或者单双引号混用了(毕竟都是一个键啊),还有就是多写了引号,我在把DW里生成的HTML代码COPY到程序里时就经常犯这个错误。<br />
5。给变量赋了非法的值<br />
如$mail=&quot;xxx@xxx.com&quot;;就是一个非法的赋值,应该写成$cgiurl=&quot;xxx@sina.com&quot;;或者使用单引号。<br />
<br />
四、遇到上面3、4、5这样的情况,最主要的工作就是定位有问题的语句。<br />
我所用的方法是这样的。<br />
<br />
################<br />
# 错误处理 #<br />
################<br />
sub error {<br />
&amp;Header('错误',&quot;错误:$_[0]&quot;);<br />
print &quot;$_[1]&quot;;<br />
&Tailer;<br />
exit 0;<br />
}<br />
<br />
##################<br />
# HTML 页面头部 #<br />
##################<br />
sub Header {<br />
my ($title,$header) = @_;<br />
<br />
print &quot;Content-type: text/htmlnn&quot;;<br />
print &quot;n&quot;;<br />
print &quot;n&quot;;<br />
print &quot; $headern&quot;;<br />
}<br />
<br />
#################<br />
# HTML 页面尾部 #<br />
#################<br />
sub Tailer {<br />
print &quot;&quot;;<br />
}<br />
<br />
将上面这个错误处理函数放在程序的最尾部,而在程序的最前面就调用它,&amp;error('调试','程序头');平时将这一句注释掉,出现500错时将注释去掉,然后就可以使用Cut&amp;Paste大法来查找错误语句了。具体方法是这样的:<br />
1)先把&amp;error()这一句到错误处理函数之间的语句Cut掉,上传执行,这样应该肯定能执行。此时应显示“错误:调试”和“程序头”字样。<br />
2)将语句Paste回来,选取一半左右的语句Cut掉,当然要注意保持函数、循环的完整性,上传,看是否能够执行。<br />
3)若能执行,有问题的语句一定在被Cut掉的那一半里,若不能执行,起码剩下的这一半语句就有问题。<br />
4)这样反复Cut&amp;Paste,很快就能找到错误语句的位置。<br />
其实实际运用中并不一定如此死板,一般来说自己改过什么地方以后才出的错心中都是有数的,只要对这些地方重点使用C&amp;P大法,效率会更高。<br />
<br />
五、除了500错误之外,更难查找的是逻辑错误<br />
查找逻辑错误只有靠设断点,观察变量值来判断错误的可能之处,这时候error这个函数又有用了,你可以方便的用它来设断点和观察变量的值,只要在想设断点的地方调用它就可以了,再把它的两个参数设为你想观察的变量,如&amp;error(&quot;abc:$abc&quot;,&quot;def:$def&quot;);将中断程序执行并输出$abc和$def的值供参考。<br />
在实际的CGI编程中,有很多错误跟由表单提交来的数据源有很大的关系,因此,查找逻辑错误时首先就要检查程序是否正确的接收了表单数据,下面的程序段就是用于显示所有表单提交给程序的数据:<br />
<br />
&amp;GetForm;<br />
&amp;ViewForm;<br />
<br />
################<br />
#显示Form数据 #<br />
################<br />
sub ViewForm{<br />
&amp;Header (','表单');<br />
foreach $key (keys %FORM){<br />
print<br />
&quot;$key:$FORM{$key}&quot;;<br />
print '<br />
';<br />
}<br />
exit 0;<br />
}<br />
################<br />
#取得Form数据 #<br />
################<br />
sub GetForm{<br />
@querys = split(/&amp;/, $ENV{'QUERY_STRING'});<br />
foreach (@querys) {<br />
($name,$value) = split(/=/, $_);<br />
&amp;SetValueToForm($name, $value);<br />
}<br />
<br />
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});<br />
@pairs = split(/&amp;/, $buffer);<br />
foreach (@pairs) {<br />
($name, $value) = split(/=/, $_);<br />
&amp;SetValueToForm($name, $value);<br />
}<br />
}<br />
<br />
################<br />
#为$FORM赋值 #<br />
################<br />
sub SetValueToForm {<br />
$name=$_[0];<br />
$value=$_[1];<br />
$name=&amp;Decode($name);<br />
$value=&amp;Decode($value);<br />
if ($FORM{$_[0]}) {<br />
$FORM{$_[0]}=&quot;$FORM{$_[0]}§$_[1]&quot;;}<br />
else {$FORM{$_[0]}=$_[1];}<br />
}<br />
<br />
##############<br />
#译码 #<br />
##############<br />
sub Decode {<br />
my ($code)=$_[0];<br />
$code =~ tr/+/ /;<br />
$code =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack(&quot;C&quot;, hex($1))/eg;<br />
return $code;<br />
}<br />
<br />
你可以把这里的几个自定义的函数都放在程序的结尾,在程序的开头都写上<br />
<br />
&amp;GetForm;<br />
#&amp;ViewForm;<br />
#&amp;error('调试','程序头');<br />
<br />
你会发现它们对你调试程序有很大的帮助。<br />
<br />
本文来源于 WEB开发网 原文链接:http://www.cncms.com.cn/cgi/782_2.htm
vfdff(作者)
2009-03-06 13:48
2
用VC++编写CGI程序<br />
浙江大学生命科学与医学工程学系 徐晨勇 段会龙 吕维雪<br />
摘 要 该文通过对CGI程序,特别是Windows CGI程序原理的分析,介绍了用Visual C+ +语言编写CGI程序的方法,并给出了一个用CGI程序使得WWW服务器与系统数据库相连的例子。<br />
关键词 CGI WWW HTML VC++ 数据库<br />
近年来,Internet与Intranet迅猛发展,企业纷纷建立自己的Intranet,以加强企业内部的联系,促进与外部世界的沟通,增强企业的竞争能力。通过建立自己的Internet服务器,企业能在网络上发布广告,介绍本公司的情况与产品,收集顾客意见,以及建立虚拟电子商场等。大家都知道写一个HTML超文本文件放在World Wide Web服务器上,即可通过各种浏览器访问你的主页,但是如何使你的静态主页能响应客户的动作,并与本地的数据库联系,将数据库的相应内容传送给远端的浏览器呢?这就需要通过CGI接口进行联系。<br />
CGI全名是Common Gateway Interface, 它是WWW服务器调用外部程序的接口通过CGI,WW W服务器能完成一些本身所力不能及的工作。<br />
在不同操作系统下CGI接口也不相同,可分为Standard CGI接口、DOS CGI接口与Win CG I接口等。Standard CGI接口用于Unix系统,它是通过环境变量来实现WWW Server与CGI应用程序之间的联系。DOS CGI接口与Standard CGI接口原理类同。Win CGI接口则与前两者大不相同。由于越来越多的WWW Server采用Windows系统,而Windows系统又不能有效地传递环境变量,由Bob Denny提出了一种Windows CGI标准,并得以不断推广。<br />
Win CGI是通过.ini文件来进行联系的。在Windows环境下,许多应用程序都是利用.ini 文件,即profile文件来定义一些基本设定,而Win CGI程序与WWW Server之间也正是通过pro file文件来实现联系的。当WWW Client通过WWW Server触发CGI程序时,WWW Server先动态生成几个文件于临时目录下,分为.ini、.inp、.out等文件。在WWW Server生成CGI程序的进程时,通过命令行参数将.ini文件的绝对路径传给CGI进程。.ini文件中也包含了.inp、.ou t等文件路径信息。这样,CGI程序可读取.ini和.inp文件所提供的信息,了解所有来自WWW Server端和与WWW Client端的数据。然后,CGI程序可以调用外部程序,或由CGI直接执行外部程序的功能,并将要传给客户端的信息以HTML文本的形式写在.out文件上。最后,WWW Server取.out文件的HTML文本,将信息传送给WWW Client端,并删除临时目录下的文件。那么,CGI的profile文件包含了什么数据呢?与Windows其它.ini文件一样,CGI profile 文件包含了许多session,每个session又包含一些key,以下是一个CGI profile的部份内容<br />
[CGI]<br />
Request Method=POST //传递方式,即HTML中的Form method有GET,POST,HEAD等。<br />
Server Software=WebSite/1.1e<br />
//Server的名称与版本。<br />
Server Name=199.199.198.55<br />
//Server的IP地址。<br />
Server Port=80//Server的Socket Port。<br />
Server Admin=tomy@vico.bme.zju.edu.cn//Server管理者的E-mail地址。<br />
Referer=http://199.199.198.55/<br />
//主页的URL路径。<br />
Remote Address=199.199.198.89<br />
//Client端的IP地址。<br />
[System]<br />
Output File=c:\WebSite\cgi-temp\198ws.out//输出文件的路径名。<br />
Content File=c:\WebSite\cgi-temp\198ws.inp//输入文件的路径名。<br />
[Form Literal]<br />
type=B//接收到的Form data即client端动作的结果信息。<br />
原则上可用来编写CGI程序的语言有:perl, AppleScript, Unix Shell, VB, C/C++等。但在Windows(NT、3x、95)环境下,还是必须借助成熟的Windows编程语言才能编写出精巧的Win CGI程序。C语言是一门深受广大程序员喜爱的语言,尤其是VCi++作为一门面向对象的语言,具备了Windows环境的许多基本功能,如OLE,ODBC等。通过ODBC这项功能,可以非常容易地连接FoxPro, Access, dBASE等多种数据库,而无需考虑各种数据库结构的差异。<br />
以下是笔者用VC++4.0编写的一个用Win CGI连接数据库的范例。使用者可在屏幕上选择,以查询ISP服务商提供的internet服务价格表。系统环境采用Windows 95,数据库采用FoxP ro2.5, WWW Server采用Website。<br />
1.建立数据库<br />
本例的CGI程序是通过ODBC连接数据库,因此数据库建完后,应用32位ODBC驱动器加以登记。<br />
2.编写HTML程序<br />
使用者可在屏幕上选择一服务类型,再按&quot;提交&quot;键,即可查询这一服务类型的各价格栏目。其HTML文本描述如下:<br />
{TITLE&gt;维科公司internet服务收费标准<br />
维科公司internet服务收费标准<br />
您要查询的类型是:<br />
A类用户<br />
B类用户<br />
C类用户<br />
D类用户<br />
3.编写VC++CGI程序<br />
Website为C++程序员提供了一个CCGI类,可在\website目录下找到。该类提供了一些方便的函数,无需程序员编写一些直接与CGI界面打交道的底层工作,充分体现面向对象语言的优势。在VC++4.0中建立一个&quot;Dialog based&quot;工程框架。将CCGI类引入框架,即将cgi.h,cgi .cpp加入程序。然后用VC++的ClassWizard工具创建一个与数据库相对应的CUserSet类,该类继承MFC类库中的CRecordSet类。<br />
主要代码加在wincgi.cpp文件中。<br />
//程序:wincgi.cpp<br />
#include &quot;stdafx.h&quot;<br />
#include &quot;wincgi.h&quot;<br />
#include &quot;cgi.h&quot;<br />
#include &quot;userset.h&quot;<br />
……<br />
void ProcessCGI(CCGI *cgi);<br />
BOOL CBaseApp::InitInstance()<br />
{<br />
CCGI cgi(m-ipCmdLine); //实例化CCGI类,并用命令行参数初始化<br />
if(cgi.CalledAsCGI())<br />
{<br />
try<br />
{<br />
ProcessCGI(&amp;cgi);<br />
//在此做所有真正的工作<br />
}<br />
catch(CException* e)<br />
{<br />
cgi.HandleException(e);<br />
//异常处理<br />
e-&gt;Delete();<br />
}<br />
}<br />
return FALSE;<br />
}<br />
void ProcessCGI(CCGI *cgi)<br />
{<br />
int i;<br />
CString strTemp, strWebmaster, strReferer;<br />
strWebmaster=cgi-&gt;GetCGIVar(&quot;Server Admin&quot;);<br />
//获得Server管理者的E-mail地址。<br />
strReferer=cgi-&gt;GetCGIVar(&quot;Referer&quot;); //获得主页的URL路径。<br />
CStringArray csaFields;<br />
cgi-&gt;EnumFormFieldNames(csaFields);<br />
//取得所有变量名,放在数组中。<br />
cgi-&gt;WriteHTMLHeader();<br />
cgi-&gt;WriteHTMLBody(&quot;VC++CGI test\015\012&quot;);<br />
cgi-&gt;WriteHTMLBody(&quot;\015\012&quot;);<br />
CString csaFieldVal;<br />
csaFieldVal=cgi-&gt;GetFormField(csaFields[0]);<br />
//得到第一个变量的值,即&quot;usertype&quot;变量的值。<br />
cgi-&gt;WriteHTMLBody(&quot;internet服务收费标准查询结果&quot;);<br />
CUserSet m-user;<br />
//实例化CUserSet类<br />
char sfilter[80];<br />
wsprintf(sfilter,&quot;USER-TYPE=&acute;%s&acute;&acute;&acute;,csaFieldVal);<br />
m-user.m-strFilter=sfilter;<br />
//设置筛选器。<br />
m-user.Open();<br />
strTemp=&quot;&quot;+m-user.m-USER-TYPE+&quot;类用户&quot;+&quot;\015\012&quot;;<br />
cgi-&gt;WriteHTMLBody(strTemp);<br />
strTemp=&quot;<br />
入网费:&quot;+m-user-FARE-INI+&quot;.\015\012&quot;;<br />
cgi-&gt;WriteHTMLBody(strTemp);<br />
……<br />
strTemp=&quot;<br />
通信费:&quot;+m-user.m-FARE-COM+&quot;.\015\012&quot;<br />
;<br />
cgi-&gt;WriteHTMLBody(strTemp);<br />
m-user.Close();<br />
if(!strReferer.IsEmpty())<br />
//设置回到主页的锚点。<br />
{<br />
cgi-&gt;WriteHTMLBody(&quot;<br />
Go<br />
cgi-&gt;WriteHTMLBody(strReferer);<br />
cgi-&gt;WriteHTMLBody(&quot;\&quot;&gt;Backwhere you came from.\015\012&quot;);<br />
}<br />
if(!strWebmaster.IsEmpty())<br />
//设置Server管理者的E-mail地址。<br />
{<br />
cgi-&gt;WriteHTMLBody(&quot;<br />
Please email comments to&quot;);<br />
cgi-&gt;WriteHTMLBody(&quot;<br />
cgi-&gt;WriteHTMLBody(strWebmaster);<br />
cgi-&gt;WriteHTMLBody(&quot;\&quot;&gt;&quot;);<br />
cgi-&gt;WriteHTMLBody(strWebmaster);<br />
cgi-&gt;WriteHTMLBody(&quot;.\015\012&quot;);<br />
}<br />
cgi-&gt;WriteHTMLBody(&quot;\015\012&quot;);<br />
cgi-&gt;WriteHTMLFooter();<br />
}<br />
4.结论<br />
将程序编译后,把wincgi.exe拷入website/cgi-win/目录下,用浏览器查询结果。至此简单地阐述了用VC++编写Win CGI程序的整个过程,C程序员也可以用自己熟悉的语言编写CGI程序了。利用VC++的强大功能,你的WWW Server将无所不能。
vfdff(作者)
2009-03-06 13:49
3
CGI(公用网关接口)规定了Web服务器调用其他可执行程序(CGI程 序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,也就是CGI程序接受Web浏览器发送给Web服务器的信息,进行处理,将响应结果再回送给Web服务器及Web浏览器。CGI程序一般完成Web网页中表单(Form)数据的处理、数据库查询和实现与传统应用系统的集成等工作。CGI程序可以用任何程序设计语言编写,如Shell脚本语言、Perl、Fortran、Pascal、C语言等。但是用C语言编写的CGI程序具有执行速度快、安全性高(因为C语言程序是编译执行且不可被修改)等特点。 <br />
<br />
  CGI接口标准包括标准输入、环境变量、标准输出三部分。 <br />
<br />
  1.标准输入 <br />
<br />
  CGI程序像其他可执行程序一样,可通过标准输入(stdin)从Web服务器得到输入信息,如Form中的数据,这就是所谓的向CGI程序传递数据的POST方法。这意味着在操作系统命令行状态可执行CGI程序,对CGI程序进行调试。POST方法是常用的方法,本文将以此方法为例,分析CGI程序设计的方法、过程和技巧。 <br />
<br />
  2.环境变量 <br />
<br />
  操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了自己的一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过 环境变量QUERY-STRING向CGI程序传递Form中的数据。 <br />
<br />
  3.标准输出 <br />
<br />
  CGI程序通过标准输出(stdout)将输出信息传送给Web服务器。传送给Web服务器的信息可以用各种格式,通常是以纯文本或者HTML文本的形式,这样我们就可以在命令行状态调试CGI程序,并且得到它们的输出。 <br />
<br />
  下面是一个简单的CGI程序,它将HTML中Form的信息直接输出到We b浏览器。 <br />
  #include <br />
  #include <br />
  main()<br />
  {<br />
   int,i,n;<br />
  printf (″Contenttype:text/plain″);<br />
  n=0;<br />
  if(getenv(″CONTENT-LENGTH″))<br />
  n=atoi(getenv(CONTENT-LENGTH″));<br />
  for (i=0;i&lt; n;i++)&gt;br&gt;   putchar(getchar());<br />
  putchar (′′);<br />
  fflush(stdout);<br />
  }<br />
<br />
<br />
  下面对此程序作一下简要的分析。<br />
<br />
  prinft (″Contenttype:text/plain″);<br />
  此行通过标准输出将字符串″Contenttype:text/plain″传送给Web服务器。它是一个MIME头信息,它告诉Web服务器随后的输出是以纯ASCII文本的形式。请注意在这个头信息中有两个新行符,这是因为Web服务器需要在实际的文本信息开始之前先看见一个空行。<br />
<br />
  if (getenv(″CONTENT-LENGTH″))<br />
  n=atoi (getenv(″CONTENT-LENGTH″));<br />
  此行首先检查环境变量CONTENT-LENGTH是否存在。Web服务器在调用使用POST方法的CGI程序时设置此环境变量,它的文本值表示Web服务器传送给CGI程序的输入中的字符数目,因此我们使用函数atoi() 将此环境变量的值转换成整数,并赋给变量n。请注意Web服务器并不以文件结束符来终止它的输出,所以如果不检查环境变量CONTENT-LENGTH,CGI程序就无法知道什么时候输入结束了。 <br />
<br />
<br />
  for (i=0;i&lt; n;i++)&gt;br&gt;   putchar(getchar());<br />
  此行从0循环到(CONTENT-LENGTH-1)次将标准输入中读到的每一个字符直接拷贝到标准输出,也就是将所有的输入以ASCII的形式回送给Web服务器。 <br />
<br />
  通过此例,我们可将CGI程序的一般工作过程总结为如下几点。<br />
  1.通过检查环境变量CONTENT-LENGTH,确定有多少输入; <br />
  2.循环使用getchar()或者其他文件读函数得到所有的输入; <br />
  3.以相应的方法处理输入;<br />
  4.通过″Contenttype:″头信息,将输出信息的格式告诉Web服务器; <br />
  5.通过使用printf()或者putchar()或者其他的文件写函数,将输出传送给Web服务器。<br />
  总之,CGI程序的主要任务就是从Web服务器得到输入信息,进行处理,然后将输出结果再送回给Web服务器。 <br />
<br />
<br />
二、环境变量<br />
<br />
  环境变量是文本串(名字/值对),可以被OS Shell或其他程序设置 ,也可以被其他程序访问。它们是Web服务器传递数据给CGI程序的简单手段,之所以称为环境变量是因为它们是全局变量,任何程序都可以存取它们。 <br />
<br />
  下面是CGI程序设计中常常要用到的一些环境变量。<br />
  HTTP-REFERER:调用该CGI程序的网页的URL。<br />
  REMOTE-HOST:调用该CGI程序的Web浏览器的机器名和域名。<br />
  REQUEST-METHOD:指的是当Web服务器传递数据给CGI程序时所采用的方法,分为GET和POST两种方法。GET方法仅通过环境变量(如QUERY-STRING)传递数据给CGI程序,而POST方法通过环境变量和标准输入传递数据给CGI程序,因此POST方法可较方便地传递较多的数据给CGI程序。 <br />
<br />
  SCRIPT-NAME:该CGI程序的名称。<br />
  QUERY-STRING:当使用POST方法时,Form中的数据最后放在QUERY-STRING中,传递给CGI程序。<br />
  CONTENT-TYPE:传递给CGI程序数据的MIME类型,通常为″applica tion/x-www-form-url encodede″,它是从HTML Form中以POST方法传递数据给CGI程序的数据编码类型,称为URL编码类型。<br />
  CONTENT-LENGTH:传递给CGI程序的数据字符数(字节数)。<br />
  在C语言程序中,要访向环境变量,可使用getenv()库函数。例如:<br />
  if (getenv (″CONTENT-LENGTH″))<br />
   n=atoi(getenv (″CONTENT-LENGTH″));<br />
  请注意程序中最好调用两次getenv():第一次检查是否存在该环境变量,第二次再使用该环境变量。这是因为函数getenv()在给定的环境变量名不存在时,返回一个NULL(空)指针,如果你不首先检查而直接引用它,当该环境变量不存在时会引起CGI程序崩溃。<br />
 <br />
<br />
三、From输入的分析和解码<br />
<br />
  1.分析名字/值对 <br />
<br />
  当用户提交一个HTML Form时,Web浏览器首先对Form中的数据以名字/值对的形式进行编码,并发送给Web服务器,然后由Web服务器传递给CGI程序。其格式如下:<br />
  name1=value1&amp;name2=value2&amp;name3=value3&amp;name4=value4&amp;...<br />
  其中名字是Form中定义的INPUT、SELECT或TEXTAREA等标置(Tag)名字,值是用户输入或选择的标置值。这种格式即为URL编码,程序中需要对其进行分析和解码。要分析这种数据流,CGI程序必须首先将数据流分解成一组组的名字/值对。这可以通过在输入流中查找下面的两个字符来完成。<br />
  每当找到字符=,标志着一个Form变量名字的结束;每当找到字符&amp; ,标志着一个Form变量值的结束。请注意输入数据的最后一个变量的值不以&amp;结束。<br />
  一旦名字/值对分解后,还必须将输入中的一些特殊字符转换成相应的ASCII字符。这些特殊字符是:<br />
  +:将+转换成空格符;<br />
  %xx:用其十六进制ASCII码值表示的特殊字符。根据值xx将其转换成相应的ASCII字符。<br />
  对Form变量名和变量值都要进行这种转换。下面是一个对Form数据进行分析并将结果回送给Web服务器的CGI程序。<br />
<br />
<br />
  #include <br />
  #include <br />
  #include <br />
  int htoi(char *);<br />
  main()<br />
  {<br />
   int i,n;<br />
  char c;<br />
  printf (″Contenttype: text/plain″);<br />
  n=0;<br />
  if (getenv(″CONTENT-LENGTH″))<br />
   n=atoi(getenv(″CONTENT-LENGTH″));<br />
  for (i=0; i&lt; n;i++){&gt;br&gt;    int is-eq=0;<br />
  c=getchar();<br />
  switch (c){<br />
   case ′&amp;′:<br />
    c=′′;<br />
    break;<br />
   case ′+′:<br />
    c=′ ′;<br />
    break;<br />
   case ′%′:{<br />
    char s[3];<br />
    s[0]=getchar();<br />
    s[1]=getchar();<br />
    s[2]=0;<br />
    c=htoi(s);<br />
    i+=2;<br />
   }<br />
   break;<br />
  case ′=′:<br />
   c=′:′;<br />
   is-eq=1;<br />
   break;<br />
  };<br />
  putchar(c);<br />
  if (is-eq) putchar(′ ′);<br />
  }<br />
  putchar (′′);<br />
  fflush(stdout);<br />
  }<br />
  /* convert hex string to int */<br />
  int htoi(char *s)<br />
  {<br />
   char *digits=″0123456789ABCDEF″;<br />
  if (islower (s[0])) s[0]=toupper(s[0]);<br />
  if (islower (s[1])) s[1]=toupper(s[1]);<br />
  return 16 * (strchr(digits, s[0]) -strchr (digits,′0′)<br />
)<br />
  +(strchr(digits,s[1])-strchr(digits,′0′));<br />
  }<br />
<br />
  上面的程序首先输出一个MIME头信息给Web服务器,检查输入中的字符数,并循环检查每一个字符。当发现字符为&amp;时,意味着一个名字/值对的结束,程序输出一个空行;当发现字符为+时,将它转换成空格; 当发现字符为%时,意味着一个两字符的十六进制值的开始,调用htoi()函数将随后的两个字符转换为相应的ASCII字符;当发现字符为=时,意味着一个名字/值对的名字部分的结束,并将它转换成字符:。最后将转换后的字符输出给Web服务器。 <br />
<br />
<br />
<br />
四、产生HTML输出<br />
<br />
  CGI程序产生的输出由两部分组成:MIME头信息和实际的信息。两部分之间以一个空行分开。我们已经看到怎样使用MIME头信息″Cont enttype:text/plain″和printf()、put char()等函数调用来输 出纯ASCII文本给Web服务器。实际上,我们也可以使用MIME头信息″C ontenttype:text/html″来输出HTML源代码给Web服务器。请注意任何MIME头信息后必须有一个空行。一旦发送这个MIME头信息给We b服务器后,Web浏览器将认为随后的文本输出为HTML源代码,在HTML源代码中可以使用任何HTML结构,如超链、图像、Form,及对其他CGI程 序的调用。也就是说,我们可以在CGI程序中动态产生HTML源代码输出 ,下面是一个简单的例子。 <br />
<br />
  #include <br />
  #include <br />
  main()<br />
  {<br />
   printf(″Contenttype:text/html″);<br />
  printf(″&lt; html&gt;″);<br />
  printf(″&lt; head&gt;&lt; /head&gt;″);<br />
  printf(″&lt; body&gt;<br />
″);<br />
printf(″&lt; h2&gt; This is an HTML page generated from with i n a CGI program..   .&lt; /h2&gt;″);<br />
  printf(″&lt; hr&gt; <br />
<br />
″);<br />
  printf(″&lt; a href=&quot;/output.html#two&quot;&gt;&lt; b&gt; Go back to out put.html page &lt; <br />
  /b&gt;&lt; /a&gt;″);<br />
  printf(″&lt; /body&gt;″);<br />
  printf(″&lt; /html&gt;″);<br />
  fflush(stdout);&lt; br&gt;   }<br />
<br />
  上面的CGI程序简单地用printf()函数来产生HTML源代码。请注意在输出的字符串中如果有双引号,在其前面必须有一个后斜字符, 这是因为整个HTML代码串已经在双引号内,所以HTML代码串中的双引号符必须用一个后斜字符来转义。 <br />
<br />
  本文详细分析了用C语言进行CGI程序设计的方法、过程和技巧。C语言的CGI程序虽然执行速度快、可靠性高,但是相对于Perl语言来说,C语言缺乏强有力的字符串处理能力,因此在实际应用中,应根据需 要和个人爱好来选择合适的CGI程序设计语言。
vfdff(作者)
2009-03-09 20:39
4
VC知识点:如何用vc6调试CGI程序 <br />
 最基本的两种方式为:<br />
 1、在vc6下点击build-&gt;start debug-&gt;attach to process,在其中选择iis进程(windosw2003下为w3wp),然后在setting-&gt;debug-&gt;Additional Dlls中添加要调试的dll;<br />
 2、在windows任务管理器中选中iis进程(windows2003下为w3wp),右键,点击调试 菜单,然后在调试工具选择对话框中选择vc6,如果在待选的即使调试器内没有vc6,则打开vc6, 选中Tools-&gt;Options-&gt;debug-&gt;just-in-time debugging 项,在设置了该选项之后,要重启计算机。<br />
<br />
 当使用以上两种方式都无效时,可以考虑在 运行 中运行命令: msdev -p 2233, 其中2233为iis的进程号id;
游客请输入验证码
浏览1936649次