用VC++編寫CGI程序
發表于:2007-07-14來源:作者:點擊數:
標簽:
近年來,Internet與Intranet迅猛發展,企業紛紛建立自己的Intranet,以加強企業內部的聯系,促進與外部世界的溝通,增強企業的競爭能力。通過建立自己的Internet 服務器 ,企業能在 網絡 上發布廣告,介紹本公司的情況與產品,收集顧客意見,以及建立虛擬電子商場等。
近年來,Internet與Intranet迅猛發展,企業紛紛建立自己的Intranet,以加強企業內部的聯系,促進與外部世界的溝通,增強企業的競爭能力。通過建立自己的Internet
服務器,企業能在
網絡上發布廣告,介紹本公司的情況與產品,收集顧客意見,以及建立虛擬電子商場等。大家都知道寫一個HTML超文本文件放在World Wide Web服務器上,即可通過各種瀏覽器訪問你的主頁,但是如何使你的靜態主頁能響應客戶的動作,并與本地的
數據庫聯系,將數據庫的相應內容傳送給遠端的瀏覽器呢?這就需要通過CGI接口進行聯系。
CGI全名是Common Gateway Interface,它是WWW服務器調用外部程序的接口通過CGI,WW W服務器能完成一些本身所力不能及的工作。
在不同操作系統下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標準,并得以不斷推廣。
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的部份內容
[CGI]
Request Method=POST //傳遞方式,即HTML中的Form method有GET,POST,HEAD等。
Server Software=WebSite/1.1e
//Server的名稱與版本。
Server Name=199.199.198.55
//Server的IP地址。
Server Port=80//Server的Socket Port。
Server Admin=tomy@vico.bme.zju.edu.cn//Server管理者的E-mail地址。
Referer=http://199.199.198.55/
//主頁的URL路徑。
Remote Address=199.199.198.89
//Client端的IP地址。
[System]
Output File=c:\WebSite\cgi-temp\198ws.out//輸出文件的路徑名。
Content File=c:\WebSite\cgi-temp\198ws.inp//輸入文件的路徑名。
[Form Literal]
type=B//接收到的Form data即client端動作的結果信息。
原則上可用來編寫CGI程序的語言有:perl, AppleScript, Unix Shell,
VB, C/C++等。但在Windows(NT、3x、95)環境下,還是必須借助成熟的Windows編程語言才能編寫出精巧的Win CGI程序。C語言是一門深受廣大
程序員喜愛的語言,尤其是VCi++作為一門
面向對象的語言,具備了Windows環境的許多基本功能,如OLE,ODBC等。通過ODBC這項功能,可以非常容易地連接FoxPro, A
clearcase/" target="_blank" >ccess, dBASE等多種數據庫,而無需考慮各種數據庫結構的差異。
以下是筆者用VC++4.0編寫的一個用Win CGI連接數據庫的范例。使用者可在屏幕上選擇,以查詢ISP服務商提供的internet服務價格表。系統環境采用Windows 95,數據庫采用FoxP ro2.5, WWW Server采用Website。
1.建立數據庫
本例的CGI程序是通過ODBC連接數據庫,因此數據庫建完后,應用32位ODBC驅動器加以登記。
2.編寫HTML程序
使用者可在屏幕上選擇一服務類型,再按"提交"鍵,即可查詢這一服務類型的各價格欄目。其HTML文本描述如下:
<HTML>
<HEAD>{TITLE>維科公司internet服務收費標準</TITLE></HEAD>
<pre><H1>維科公司internet服務收費標準</H1>
</P>
<hr><form method="POST" action="cgi-win/wincgi.exe">
您要查詢的類型是:
<UL><LI>A類用戶<input name="usertype" type=radio value="A">
<LI>B類用戶<input name="usertype" type=radio value="B">
<LI>C類用戶<input name="usertype" type=radio value="C">
<LI>D類用戶<input name="usertype" type=radio value="D">
</UL>
<center>
<input type=submit value="提交"> <input type=reset value="取消"></center>
</pre></form><hr>
</HTML>
3.編寫VC++CGI程序
Website為C++程序員提供了一個
CCGI類,可在\website目錄下找到。該類提供了一些方便的函數,無需程序員編寫一些直接與CGI界面打交道的底層工作,充分體現面向對象語言的優勢。在VC++4.0中建立一個"Dialog based"工程框架。將CCGI類引入框架,即將cgi.h,cgi .cpp加入程序。然后用VC++的ClassWizard工具創建一個與數據庫相對應的CUserSet類,該類繼承MFC類庫中的CRecordSet類。
主要代碼加在wincgi.cpp文件中。
//程序:wincgi.cpp
#include "stdafx.h"
#include "wincgi.h"
#include "cgi.h"
#include "userset.h"
……
void ProcessCGI(CCGI *cgi);
BOOL CBaseApp::InitInstance()
{
CCGI cgi(m-ipCmdLine); //實例化CCGI類,并用命令行參數初始化
if(cgi.CalledAsCGI())
{
try
{
ProcessCGI(&cgi);
//在此做所有真正的工作
}
catch(CException* e)
{
cgi.HandleException(e);
//異常處理
e->Delete();
}
}
return FALSE;
}
void ProcessCGI(CCGI *cgi)
{
int i;
CString strTemp, strWebmaster, strReferer;
strWebmaster=cgi->GetCGIVar("Server Admin");
//獲得Server管理者的E-mail地址。
strReferer=cgi->GetCGIVar("Referer"); //獲得主頁的URL路徑。
CStringArray csaFields;
cgi->EnumFormFieldNames(csaFields);
//取得所有變量名,放在數組中。
cgi->WriteHTMLHeader();
cgi->WriteHTMLBody("<HEAD><TITLE>VC++CGI test</TITLE></HEAD>\015\012");
cgi->WriteHTMLBody("<BODY>\015\012");
CString csaFieldVal;
csaFieldVal=cgi->GetFormField(csaFields[0]);
//得到第一個變量的值,即"usertype"變量的值。
cgi->WriteHTMLBody("<h1>internet服務收費標準查詢結果</h1><hr>");
CUserSet m-user;
//實例化CUserSet類
char sfilter[80];
wsprintf(sfilter,"USER-TYPE='%s''',csaFieldVal);
m-user.m-strFilter=sfilter;
//設置篩選器。
m-user.Open();
strTemp="<h2>"+m-user.m-USER-TYPE+"類用戶"+"</h2>\015\012";
cgi->WriteHTMLBody(strTemp);
strTemp="<P>入網費:"+m-user-FARE-INI+".</P>\015\012";
cgi->WriteHTMLBody(strTemp);
……
strTemp="<P>通信費:"+m-user.m-FARE-COM+".</P>\015\012"
;
cgi->WriteHTMLBody(strTemp);
m-user.Close();
if(!strReferer.IsEmpty())
//設置回到主頁的錨點。
{
cgi->WriteHTMLBody("<P>Go<A HREF=\"");
cgi->WriteHTMLBody(strReferer);
cgi->WriteHTMLBody("\">Back</A>where you came from.</P>\015\012");
}
if(!strWebmaster.IsEmpty())
//設置Server管理者的E-mail地址。
{
cgi->WriteHTMLBody("<P>Please email comments to");
cgi->WriteHTMLBody("<A HREF=\"mailto:");
cgi->WriteHTMLBody(strWebmaster);
cgi->WriteHTMLBody("\">");
cgi->WriteHTMLBody(strWebmaster);
cgi->WriteHTMLBody("</A>.</P>\015\012");
}
cgi->WriteHTMLBody("</BODY>\015\012");
cgi->WriteHTMLFooter();
}
4.結論
將程序編譯后,把wincgi.exe拷入website/cgi-win/目錄下,用瀏覽器查詢結果。至此簡單地闡述了用VC++編寫Win CGI程序的整個過程,C程序員也可以用自己熟悉的語言編寫CGI程序了。利用VC++的強大功能,你的WWW Server將無所不能。
原文轉自:http://www.anti-gravitydesign.com