Database 版 (精华区)

发信人: joy (处处好风光), 信区: Database
标  题: 关于isapi
发信站: 紫 丁 香 (Fri Jun 25 21:22:30 1999), 转信

利用ISAPI建立网络应用程序
                     joy  版权所有
摘要:本文介绍了实现Web交互的两种方法,CGI及ISAPI。对它们的原理、 实现方法作了
阐述,并就它们的性能进行了比较。最后简单介绍了ISAPI应用的一个实例。
关键词:WWW CGI ISAPI DLL
一 引言 
WWW(World Wide 
Web)是因特网上一个分布式的多信息组合信息系统。此信息系统采用客户机/服务器模式
和超文本链接方式,以统一的方式将网络上不同数据组合在一个文档中,使它们能够方便
得被用户访问。WWW服务采用的应用层协议是HTTP协议。从数据类型来说,WWW主要有两种
服务方式:静态访问和
动态访问。静态访问是指当用户发出访问请求后,WWW服务器将事先生成的Web页面直接返
回给用户。动态访问是指用户发出请求后,WWW服务器把用户请求通过相应的接口传给后
台其他服务进程进行处理。后台程序根据用户请求的参数,动态生成文件,并将其返回
WWW服务器,再由服务器将
文件返回给用户。对于基于因特网的该系统来说,用户提交的信息后要经过服务器方应用
程序处理才能得到返回结果,因此必须采用动态访问方式。
二 ISAPI与CGI比较
网络应用以WWW方式发布信息和处理从表单接受来的信息,对于由表单接收来的信息,我们
用ISAPI来处理,我们为什么使用ISAPI呢?而不使用CGI呢? 通常,Web 节点是由静态的超
文本标记语言( HTML,Hypertext 
MarkupLanguage)组成,交互作用是通过外部过程,即服务器端的公用网关接口 (CGI,
Common Gateway Interface)应用程序或脚本来实现的。例如,如果我们需要访问不是以 
HTML 形式存贮的数据,就必须用 CGI 应用程序来访问数据,然后把结果送回到客户端。
  ISAPI 是一种标准的编程接口,Web 开发者可用它编写交互式应用程序。ISAPI 扩展
(Extension)应用程序具有 CGI 脚本同样的功能,但它比CGI 具有更快、更有效的性能
。ISAPI for Windows NT 编写的应用程序,Web 用户可通过填写 HTML 表单(Form)或
单击 Web 节点上 
HTML 页面中的链接来激活该应用程序。服务器端获取用户提供的信息后,被激活的ISAPI
 应用程序对获取的信息作出处理。根据 ISAPI 应用程序的功能或把获取的信息存入数据
库,或以获取的信息为条件访问数据库中的数据,然后把结果以 HTML 页面的形式送回到
客户端。ISAPI 
的应用程序被编译为动态链接库(DLL, Dynamic Linked Library),该库在WWW服务(
Service)启动时装载入内存。它要求较少的系统开销,性能明显优于 CGI 应用程序。因
为每个请求并不启动单独的进程。而如用 CGI作交互程序,每个请求需要启动单独的进程
。ISAPI 
的另一个特征是允许预处理请求和后处理响应。允许超文本传输协议 (HTTP) 请求和响应
的特定节点处理。ISAPI 筛选程序可用于自定义的身份验证、访问或记录等应用程序。可
使用 ISAPI 筛选程序和应用程序创建非常复杂的节点。可以组合 ISAPI 扩展和 Internet
 
数据库连接器以创建高级交互式节点。 
这两种应用程序在网络数据库查询中的执行流程如下:
(一).其访问流程如下:

 客户通过WWW以表单形式发送请求 , 客户浏览器发送到服务器的 URL 包含 CGI 脚本或要
运行的应用程序名。服务器将文件扩展名与服务器的脚本映射注册表项进行对比,确定启
动哪个可执行文件。为了允许服务器启动不带扩展名映射的 CGI 
应用程序类型,将此应用程序类型的条目添加到注册表项。服务器利用环境变量将信息传
递至 CGI 
应用程序,然后启动应用程序。部分变量是与服务器相关的;主要部分来自客户浏览器,
并和客户浏览器或正发送的请求相关。应用程序执行其处理。如果合适,应用程序则以客
户可接收的格式将数据写入标准输出流 (STDOUT)。应用程序在返回数据时必须依照特定
格式:   
1. 第一行或包含服务器指令的行,必须为 MIME 内容类型。其它服务器伪指令是 Locatio
n(它重定向客户到另一个文档或返回另一个文档)与 Status。 
2. 服务器伪指令之后必须是空行。 
3. 应用程序返回到客户的数据紧跟空行。  
服务器获取它从 STDOUT 接收的数据,并添加标准 HTTP 标题。然后将 HTTP 消息回传客
户。
(二). ISAPI的访问流程如下: 
    
ISAPI的应用程序同CGI脚本是类似的,它们对单个请求提供完整的处理(或一组要求)。
在ISAPI模型中,通过DLL(动态链接库)处理请求。由ISAPI扩展DLL处理表单请求。处理
第一次表单请求时,服务器将扩展装入内存。扩展将驻留在内存中,直到服务器关闭为止
。当请求准备用扩展时
,网络服务器调用DLL,传送给它与用户请求相应的数据。如果一个扩展的多个请求同时
到达,服务器就产生一个新的线程,调用扩展DLL的同一拷贝。这种模型显然优于NT平台
上的CGI模型。由于扩展装入后仍驻留,服务器就不必装入程序拷贝来为每个请求服务。
扩展的每个请求将会是服务器产生线程,而不是进程。这是一个更廉价的操作。其访问流
程如图。
三 ISAPI的一个实例
   下面是个简单的例子,功能只是将将一个表格发给用户,功能简单,但是具备一个典型的ISAPI全部流程。源程序如下(大部分为Wizard 生成的代码):
(一) 主程序
     // SENDTABLE.CPP - Implementation file for your Internet Server
//    SendTable Extension

#include "stdafx.h"
#include "SendTable.h"

///////////////////////////////////////////////////////////////////////
// The one and only CWinApp object
// NOTE: You may remove this object if you alter your project to no
// longer use MFC in a DLL.

CWinApp theApp;

///////////////////////////////////////////////////////////////////////
// command-parsing map

BEGIN_PARSE_MAP(CSendTableExtension, CHttpServer)
        // TODO: insert your ON_PARSE_COMMAND() and 
        // ON_PARSE_COMMAND_PARAMS() here to hook up your commands.
        // For example:
        /*******my codes begin here********/
        ON_PARSE_COMMAND(sendtable, CSendTableExtension, ITS_EMPTY)
        DEFAULT_PARSE_COMMAND(sendtable, CSendTableExtension)
        /**********my codes end here***********/
END_PARSE_MAP(CSendTableExtension)


///////////////////////////////////////////////////////////////////////
// The one and only CSendTableExtension object
CSendTableExtension theExtension;
///////////////////////////////////////////////////////////////////////
// CSendTableExtension implementation
CSendTableExtension::CSendTableExtension()
{
}
CSendTableExtension::~CSendTableExtension()
{
}
BOOL CSendTableExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
{
        // Call default implementation for initialization
        CHttpServer::GetExtensionVersion(pVer);
        // Load description string
        TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
        ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
                        IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN));
        _tcscpy(pVer->lpszExtensionDesc, sz);
        return TRUE;
}

///////////////////////////////////////////////////////////////////////
// CSendTableExtension command handlers
        /****************my codes begin here**********************/
void CSendTableExtension::sendtable(CHttpServerContext* pCtxt)
{
        StartContent(pCtxt);
        WriteTitle(pCtxt);
        int     test1=1;
        CString test2="张三";
        *pCtxt << _T("<center><h2>姓名表</h2></center>\r\n");
        *pCtxt << _T("<center><table border=5>");
        *pCtxt << _T("<tr><th>学号</th></tr>");
        *pCtxt << _T("<tr>");
        *pCtxt << _T("<td>"<<test1<<"</td></tr>\r\n");
        *pCtxt << _T("<tr><th>姓名</th></tr><tr><td>"<<test2
<<"</td></tr>\r\n");
        *pCtxt << _T("</table></center>\r\n");
        EndContent(pCtxt);
}
        /*****************my codes end here**********************/
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CSendTableExtension, CHttpServer)
        //{{AFX_MSG_MAP(CSendTableExtension)
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif  // 0
(二) 主头文件
#if !defined(AFX_SENDTABLE_H__27FA8D85_F0A3_11D2_AEA6_000025002CAC__INCLUDED_)
#define AFX_SENDTABLE_H__27FA8D85_F0A3_11D2_AEA6_000025002CAC__INCLUDED_
// SENDTABLE.H - Header file for your Internet Server
//    SendTable Extension
#include "resource.h"
class CSendTableExtension : public CHttpServer
{
public:
        CSendTableExtension();
        ~CSendTableExtension();
// Overrides
        // ClassWizard generated virtual function overrides
                // NOTE - the ClassWizard will add and remove member functions here.
                //    DO NOT EDIT what you see in these blocks of generated code !
        //{{AFX_VIRTUAL(CSendTableExtension)
        public:
        virtual BOOL GetExtensionVersion(HSE_VERSION_INFO* pVer);
        //}}AFX_VIRTUAL
        // TODO: Add handlers for your commands here.
        // For example:
      /*************my codes begin here**************/
        void sendtable(CHttpServerContext* pCtxt);
          /*************my codes end here**************/
        DECLARE_PARSE_MAP()
        //{{AFX_MSG(CSendTableExtension)
        //}}AFX_MSG
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately 
before the previous line.
#endif // !defined(AFX_SENDTABLE_H__27FA8D85_F0A3_11D2_AEA6_000025002CAC__
INCLUDED)
(三) 动态链接库定义文件
; SENDTABLE.def : declares the module parameters for the DLL.
LIBRARY      "SENDTABLE"
EXPORTS
        HttpExtensionProc
        GetExtensionVersion
将上述文件编译后生成DLL文件,将其放在有可执行权限的Scripts目录下,用<form 
action="/Scripts/SendTable.dll?" method="POST">的方式查看效果。
四 结论
   以上给出了CGI与ISAPI的比较,并给出了一个实例。由于ISAPI编译后生成DLL文件,
调试较困难。如果程序处理不当还容易造成崩溃。所以使用时,一定要注意。
  
 

--
※ 修改:.yunguo 于 Jun 29 09:48:48 修改本文.[FROM: 202.118.243.170]
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.229.134]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.270毫秒