一、引言
ISAPI與CGI都屬于通用的網關接口,主要用來實現WWW服務器與客戶端的信息交互。
隨著WWW爆炸式的發展及其日益普及,人們的眼光已被充斥其上的商機所吸引。在WWW上求取經濟利益的方式主要有以下幾種:
通過為企業等作廣告宣傳收取廣告費;
向入網觀看者收取訂閱費;
直接在網上出售商品和服務。
目前大多數網站提供信息的方式是由用戶通過客戶瀏覽器(如Netscape或Explorer等)與WWW服務器連接,然后用鼠標點按超連接以瀏覽相關主頁。在此過程中,基本上是服務器向客戶端單方向的信息傳遞,隨著服務需求的不斷擴大,這種單純的單方向傳遞信息的靜態主頁已不能滿足需求。不論是服務提供方還是客戶,都希望瀏覽服務器將信息發送到用戶同時,用戶端也能將信息發送到服務器端,實現服務器與客戶的交互。典型的應用如:用戶登記表、用戶留言板以及用戶通過WWW檢索服務器端的數據庫等。
要實現一個可與用戶交互信息的服務系統,所需增加的有兩項:交互式主頁和用戶輸入信息處理程序。交互式主頁即有輸入信息的編輯框,選擇菜單按鈕之類的主頁,以供用戶輸入信息;用戶輸入的信息則交由用戶信息處理程序處理。實現該程序可以有多種途徑,該程序可以放在服務器端,也可以放在客戶機端,前者如CGI、ISAPI,后者如JAVAAPPLET等。本文只討論前者,將闡述ISAPI的優點,并就其實現舉例說明。
二、WEB交互環境的實現
2.1交互式主頁
要實現WEB上的交互環境,用戶必須能夠在他瀏覽到的主頁上輸入信息,這就是一個交互式的主頁。一般來說,用戶輸入信息的形式有填寫編輯框,點選無線按鈕等選擇框及選擇下拉菜單等,所以交互主頁也必須有這些輸入元素項。下面是一個簡單的交互主頁例子:
交互式主頁HTML源文件:isapi1.htm
「HTML」
「TITLE」TEST「/TITLE」
「HEAD」
ISAPITEST
「/HEAD」
「BODY」
「formaction="/gjy/isapi1/debug/isapi1.dll?RegisterUser"method=post」
InputyourRegisterInfomation:「br」
Name:「inputtype="text"name="First"」「br」
Address:「inputtype="text"name="Middle"」「br」
Email:「inputtype="text"name="Last"」「br」「p」
「inputtype="submit"」
「inputtype="reset"」「/p」
「/form」
「/body」
「/html」
通過Explorer瀏覽器打開該文件,可以看到如下效果(編輯框中已輸入內容):
2.2實現交互主頁的途徑。
從上述主頁制作描述可見,一個交互式主頁的制作是很簡單的,但要真正實現與用戶的交互,還必須要有應用程序的參與。這個程序可以屬于多種樣式,如CGI、JAVAAPPLET以及ISAPI。在上述主頁文件中,有一項:
「formaction="/gjy/isapi1/debug/isapi1.dll?RegisterUser"method=post」
這里就指明了對應處理該主頁輸入信息的程序(isapi1.dll),這是ISAPI的應用程序動態連接庫。對于CGI應用程序也是一樣的處理。
一般來說,該程序的功能就是要將用戶輸入信息傳到服務器應用程序。
CGI是大家都比較熟悉的一種實現上述功能的有效途徑,也可能是當前最為流行的一種,而ISAPI是微軟獨特的具有類似CGI功能的網絡應用接口標準。ISAPI在性能上較之CGI具有許多優良特性。下面我們簡單介紹一下CGI與ISAPI以及它們之間的性能差別。
三、CGI原理及其性能
3.1CGI概念
CGI即通用網關接口(CommonGatewayInterface),它是一個WWW服務器
主機對外服務的標準接口,一般來說,一個CGI接口的功能就是在超文本文件和服務器主機應用程序間傳遞信息。
3.2CGI程序語言
事實上,任何一種程序語言,只要能在服務器主機上利用CGI接口來編寫應用程序,都可以叫作CGI程序語言。目前最為流行的CGI程序語言有四種:C,Shell,Perl和VisualBasic,其它一些語言也有許多人在用,如TCL,Fortran及AppleScript等。
3.3CGI程序的執行
CGI程序一般是個可執行程序。編譯好的CGI程序一般要集中放在一個目錄下。具體存放的位置隨操作系統的不同而不同,例如UNIX系統下是放在cgi-bin子目錄下,而在Windows操作系統下(注意,這里不包括NT4.0)以Webstar或Website作WWW服務器,CGI程序都放在cgi-win下。CGI程序的執行一般有兩種調用方式:1是通過URL直接調用,如:“http://202.114.2.182/cgi-win/cgi.exe”,在瀏覽器的URL欄里直接寫入上述描述就可以調用該程序;另一種方式,也是主要的方式,是通過交互式主頁里的FORM欄調用,通常都是用戶在填完一張輸入信息主頁后按確認按鈕啟動CGI程序,前面的交互主頁就是一個如此調用CGI的典型例子。
3.4CGI工作的主要流程
CGI工作的主要流程是:1.一個用戶請求激活一個CGI應用程序;2.CGI應用程序將交互主頁里用戶輸入信息提取出來;3.將用戶輸入的信息傳給服務器主機應用程序(如數據庫查詢〕;4.將服務器處理結果通過HTML文件返回給用戶;5.CGI進程結束。
3.5CGI的性能評價
CGI的跨平臺性能極佳,幾乎可以在任何操作系統上實現,如DOS、WINDOWS、UNIX、OS/2、Macintosh等。實現CGI的編程語言也有很多選擇。CGI的應用程序一般都是一個獨立的可執行程序,和WWW服務器各自占據著不同的進程,而且一般一個CGI程序只能處理一個用戶請求。這樣,每有一個用戶請求,都會激活一個CGI進程,當用戶請求數量非常多時,會大量擠占系統的資源如內存,CPU時間等,造成效能低下。
四、ISAPI原理及其性能
4.1ISAPI概念
ISAPI即InternetServerApplicationProgramInterface,是微軟提供的一套面向Internet服務的API接口,它能實現CGI能提供的全部功能,并在此基礎上進行了擴展,如提供了過濾器應用程序接口。
4.2ISAPI程序語言
由于開發ISAPI應用要用到微軟的一套API,所以能用來開發ISAPI應用的語言不如CGI那么多。主要有VisualC++4.1以上版本,VisualBasic5.0、BorlandC++5.0也可以。
4.3ISAPI原理
ISAPI的工作原理和CGI大體上是相同的,都是通過交互式主頁取得用戶輸入信息,然后交服務器后臺處理。但是二者在實現機制上大相庭徑。ISAPI與CGI最大的區別在于:不同于CGI,在ISAPI下建立的應用程序是以動態連接庫的形式存在;而CGI的應用程序一般都是可執行程序。
4.4ISAPI程序的執行
ISAPI應用的工作流程與CGI有一些不同。ISAPI應用的DLL不僅可以象CGI程序一樣被用戶請求激活,還可以被系統預先激活來監視用戶輸入;對于被用戶激活的DLL,在處理完一個用戶請求后不會馬上消失,而是繼續駐留在內存中等待處理別的用戶輸入,直到過了一段時間后一直沒有用戶輸入。
4.5ISAPI性能評價
一個ISAPI的DLL,可以在被用戶請求激活后長駐內存,等待用戶的另一個請求,還可以在一個DLL里設置多個用戶請求處理函數,此外,ISAPI的DLL應用程序和WWW服務器處于同一個進程中,效率要顯著高于CGI。
不過ISAPI的平臺兼容性較差,目前只能用于微軟自己的Windows95和NT操作系統上,服務器平臺也僅限于IIS(InternetInformationServer)和MSpersonalwebserver以及NTworkstation上的peerwebserver。
五、ISAPI的實現
能夠支持ISAPI開發的平臺只有微軟的幾個平臺組合(如NT+IIS,WIN95+MSpersonalwebserver)。因此開發ISAPI只能這幾個平臺上。開發語言前已有述,這里向大家推薦VisualC++4.2版,它的Wizard提供了專門制作ISAPI的功能項。
下面是個簡單的例子,功能是將用戶從瀏覽器上的輸入簡單地回顯給用戶,功能簡單,但是具備一個典型的ISAPI全部流程。源程序如下(大部分為Wizard生成的代碼):
1.主程序:
//ISAPI1.CPP-ImplementationfileforyourInternetServer
#include"stdafx.h"
#include"isapi1.h"
///////////////////////////////////////////////////////////////////////
//TheoneandonlyCWinAppobject
//NOTE:Youmayremovethisobjectifyoualteryourprojecttono
//longeruseMFCinaDLL.
CWinApptheApp;
///////////////////////////////////////////////////////////////////////
//command-parsingmap
BEGIN_PARSE_MAP(CIsapi1Extension,CHttpServer)
/*************Mycodesbeginhere***********/
ON_PARSE_COMMAND(RegisterUser,
CIsapi1Extension,ITS_PSTRITS_PSTRITS_PSTR)
ON_PARSE_COMMAND_PARAMS("FirstMiddleLast")
/*************Mycodesendhere***********/
END_PARSE_MAP(CIsapi1Extension)
///////////////////////////////////////////////////////////////////////
//TheoneandonlyCIsapi1Extensionobject
CIsapi1ExtensiontheExtension;
///////////////////////////////////////////////////////////////////////
//CIsapi1Extensionimplementation
CIsapi1Extension::CIsapi1Extension()
{
}
CIsapi1Extension::~CIsapi1Extension()
{
}
BOOLCIsapi1Extension::GetExtensionVersion
(HSE_VERSION_INFO*pVer)
{
//Calldefaultimplementationforinitialization
CHttpServer::GetExtensionVersion(pVer);
//Loaddescriptionstring
TCHARsz[HSE_MAX_EXT_DLL_NAME_LEN+1];
ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
IDS_SERVER,sz,HSE_MAX_EXT_DLL_NAME_LEN));
_tcscpy(pVer->lpszExtensionDesc,sz);
returnTRUE;
}
///////////////////////////////////////////////////////////////////////
//CIsapi1Extensioncommandhandlers
/******Mycodebeginshere**********/
voidCIsapi1Extension::RegisterUser
(CHttpServerContext*pctxt,LPCTSTR
pstrFirst,LPCTSTRpstrMiddle,LPCTSTRpstrLast)
{
//doprocessinghere!
*pctxt<<_T("Yournameis:");
*pctxt<<_T(pstrFirst);
*pctxt<<_T("\n");
*pctxt<<_T("YourAddressis:");
*pctxt<<_T(pstrMiddle);
*pctxt<<_T("\n");
*pctxt<<_T("YourE_mailis:");
*pctxt<<_T(pstrLast);
}
/*********Mycodesendhere**********/
//Donoteditthefollowinglines,
whichareneededbyClassWizard.
#if0
BEGIN_MESSAGE_MAP(CIsapi1Extension,CHttpServer)
//{{AFX_MSG_MAP(CIsapi1Extension)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif//0
2.主頭文件
//ISAPI1.H-HeaderfileforyourInternetServer
//isapi1Extension
#include"resource.h"
classCIsapi1Extension:publicCHttpServer
{
public:
CIsapi1Extension();
~CIsapi1Extension();
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//NOTE-theClassWizardwilladdandremovememberfunctionshere.
//DONOTEDITwhatyouseeintheseblocksofgeneratedcode!
//{{AFX_VIRTUAL(CIsapi1Extension)
public:
virtualBOOLGetExtensionVersion(HSE_VERSION_INFO*pVer);
//}}AFX_VIRTUAL
//TODO:Addhandlersforyourcommandshere.
/***********Mycodedbeginhere(函數聲明)*********/
voidRegisterUser(CHttpServerContext*pctxt,
LPCTSTRpstrFirst,LPCTSTR
pstrMiddle,LPCTSTRpstrLast);
/*********Mycodesendhere
DECLARE_PARSE_MAP()
//{{AFX_MSG(CIsapi1Extension)
//}}AFX_MSG
};
3.動態連接庫定義文件
/*************************************/
/*ISAPI1.def*/
/*************************************/
;ISAPI1.def:declaresthemoduleparametersfortheDLL.
LIBRARY"ISAPI1"
EXPORTS
HttpExtensionProc
GetExtensionVersion
在上述程序中,定義了一個CHttpServer的類CIsapi1Extension,這是該程序的主要一個類,通過它實現與用戶交互的功能。由ON_PARSE_COMMAND段實現函數映射,上述程序中定義了該DLL中的一個成員函數RegisterUser,其功能就是將用戶在編輯框中輸入的信息發送回用戶。關于具體實現細節,可以參看VC4.2幫助文檔。
將上述文件編譯成DLL后放入服務器主機內WWW服務器指定的用戶有執行權限的Scripts目錄里,該目錄的邏輯名應和交互主頁里的一致。設置完后,通過瀏覽器連到服務器上,瀏覽該主頁,并輸入信息到編輯框中。
文章來源于領測軟件測試網 http://www.kjueaiud.com/