使 用MFC 开 发ISAPI Extensions 程 序.docx

上传人:b****6 文档编号:7952134 上传时间:2023-01-27 格式:DOCX 页数:12 大小:23.26KB
下载 相关 举报
使 用MFC 开 发ISAPI Extensions 程 序.docx_第1页
第1页 / 共12页
使 用MFC 开 发ISAPI Extensions 程 序.docx_第2页
第2页 / 共12页
使 用MFC 开 发ISAPI Extensions 程 序.docx_第3页
第3页 / 共12页
使 用MFC 开 发ISAPI Extensions 程 序.docx_第4页
第4页 / 共12页
使 用MFC 开 发ISAPI Extensions 程 序.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

使 用MFC 开 发ISAPI Extensions 程 序.docx

《使 用MFC 开 发ISAPI Extensions 程 序.docx》由会员分享,可在线阅读,更多相关《使 用MFC 开 发ISAPI Extensions 程 序.docx(12页珍藏版)》请在冰豆网上搜索。

使 用MFC 开 发ISAPI Extensions 程 序.docx

使用MFC开发ISAPIExtensions程序

使用MFC开发ISAPIExtensions程序

1.引言

----1.1ISAPI与CGI

----通用网关接口CommonGatewayInterface(CGI)很早就作为交

互式的Web应用程序的一个标准广泛应用在Internet之中。

CGI脚本允许人们用多种编程语言(如Basic、C、Perl、Shell等

等)来编写简单的应用程序。

这些脚本运行在Web服务器上,

而在客户的Web浏览器上输出运行结果。

客户的输入通过

环境变量或者标准输入设备来进行传递,然后CGI程序根

据需要完成特定的功能,并通过标准输出设备送回HTML格

式的结果显示在客户的浏览器中。

CGI的这一特性—设计

简单,再加上它支持多种编程语言,使得开发CGI应用程序

非常简单。

尽管如此,人们在使用中还是发现了CGI应用程

序的一个很大的缺点:

性能不高。

虽然有不少办法来使CGI应

用程序运行得更快一些(如把它们变成编译好的二进制代

码,而不用Perl脚本),但执行速度仍然是一个问题。

每当

通过Web访问一个CGI程序时,CGI执行文件(或者脚本的解释

器)都要为每一个请求创建一个新的进程。

对于一个信息

量比较大的站点来说,这无疑给服务器增加了一个沉重的负担。

----当微软开始开发自己的Web服务器(MicrosoftInternetInformation

Server或简称为IIS)时,意识到了CGI的这一大的缺陷,于是他

们就引入了ISAPI。

----ISAPI使用动态链接库DLL而不是可执行代码。

这些DLLs被

装入到服务器的内存空间。

由于代码在内存中缓存起来了,

而不是每次接收到请求时再装入到内存中,因此这一技术极

大地提高了交互式的Web应用程序的性能。

----ISAPI程序分为两种:

一种就是我们要介绍的ISAPIExtensions,

它提供了一种比CGI更好的实现方法;另一种称作ISAPIFilter,

它可以对服务器上进入或出去的数据进行过滤。

----总的来说,ISAPI优于CGI之处包括:

----①速度快:

ISAPI在性能上有很大的提高;

----②功能强:

ISAPI还可以创建Filter以对数据进行预处理。

并且它完全与MFC集成在一起了。

----相反,ISAPI的不足之处有:

----①标准化不够:

目前只有一部分服务器支持ISAPI;

----②开发困难:

相关资料很少,并且调试很麻烦。

----1.2ISAPI基础

----ISAs开发主要基于MFC的CHttpServer类。

该类控制了所

有与服务器的交互操作,同时还包含

了用于客户请求的所有函数。

尽管一个ISA只能有CHttpServer类

的一个实例,但

每个ISA仍然可以同时处理多个请求。

这是通过CHttpServer类为

每个请求创建

一个CHttpServerContext类来实现的。

CHttpServerContext类包含了每个

特定请求的所有数据以

及由ISA返回到客户的所有HTML代码。

----ISAPIDLLs的调用方法和CGI一样:

在客户端使用GET或POST方法。

例如,当客户作出下列请求时:

----

----"name"域和"id"域以及与它们相关的数据都被传递给ISA。

ISAPI在使用这些相关的数据之前把它们存放在相应的数据

结构中,这是通过一个请求映射系统来实现的。

----每一个请求都有一个解析映射表。

通过定义服务器从

客户接收的数据的类型和顺序,该解析映射表可以把数

据传递到合适的数据结构中。

例如,对于请求"name=fisherman&id=12345",

解析映射表将显示一个字符串和一个整型数,并且

"fisherman"and"12345"将被解析出来存放到各自的数据结构中。

 

----解析映射系统还有另外一个功能:

ISAPI可以把请求传

递给ISA内特定的成员函数。

请求字符串可以包含一个命令,

解析映射表就使用该命令把请求传递给ISA内正确的成员函数。

----由于ISAPI使用命令驱动机制来处理请求,因此在开始

开发ISA程序时可能会觉得有些麻烦,但是一旦学会了,用

户就会发现这是一个非常强大的处理请求的方法。

----2.使用MFC开发ISA程序

----2.1建立工程

----开发ISA的第一步工作是建立一个工程。

和创建其它

VisualC++(VC++)工程一样,创建ISA也有一个wizard来指导用

户完成初始的步骤。

打开VC++,在File菜单中选择New,然后

在对话框中选择Projects面板,在下面的列表中选择

"ISAPIExtensionWizard"工程类型,选择适当的路径,并把它

命名为"HelloWeb",如图1所示。

图1 New对话框

----接着选择Ok按钮,于是出现一个对话框让用户选择预

创建的ISAPI程序类型,缺省情况下是ISA程序,同时MFC被设

置为动态链接。

如果用户开发的服务器上有了这些MFCDLLs,

这当然是可以的。

但是如果没有安装DeveloperStudio,通常情

况下这些DLLs是没有的,这样用户的ISA将无法运行。

此时应

该把工程设置为静态链接。

我们建议用户这样设置,如图2

所示。

图2 ISAPIExtensionwizard对话框

----接着选择Finish按钮。

VC++将显示一个对话框给用户一些

关于新工程的提示信息。

在此对话框中选择OK。

----现在工程已经创建好了,现在该处理一些复杂点的问

题了。

我们在前面提到过,ISA在运行时是IIS的一部分,而IIS

又作为NT的一个服务而运行。

这一事实使用调试过程变得

复杂了,因为在IIS运行时,VC++的调试器不能够接管ISA。

了解决这个问题,微软公司以两种形式发行了IIS:

作为一

项服务,以及作为一个单独的可执行程序。

对于后一种情

况,我们就可以在命令行上来控制服务器。

虽然这样可以

解决上述问题并使得开发过程变得容易一些,但实现起来

显得很繁琐。

下面我们来介绍这个过程。

----当用户处于debug调试模式时,VC++(以及IIS)将在用户的

帐号和权限下运行。

由于通常IIS完成的一些工作是不允许

大多数用户有相应的权限的,因此用户(或用户的系统管

理员)需要做以下工作:

----①在桌面上选择“开始\程序\管理工具(公用)\域用户

管理器”,打开域用户管理器;

----②在“规则”菜单中选择“用户权限”;

----③选择“显示高级用户权限”检查框;

----④在“权限”下拉列表中选择“以操作系统方式操作”;

----⑤选择“添加”按钮得到“添加用户及组”对话框,选择

“显示用户”按钮,并在“名称”列表中选择用户使用的帐

号,然后选择“添加”按钮;

----⑥选择“确定”按钮;

----⑦对“产生安全审核”权限重复上述步骤。

----为了使这些设置生效,用户必须先退出登录,然后再登

录回来。

----IIS中包含了三项服务:

FTPPublishingService,GopherPublishing

Service和WorldWideWeb。

由于调试器要在命令行上运行IIS,所以

所有这三项服务都必须停止。

这可以通过“控制面板”中的

“服务”程序或者使用IIS的“Internet服务管理器”来实现。

果需要进行大量的调试工作,我们建议用户通过“控制面板”

中的“服务”程序来关闭IIS服务并禁止它们自动启动,这样可

以避免用户每次启动计算机时都要进行关闭服务的操作。

----接下来就必须对工程进行一些配置了:

----①在Project菜单中选择Settings菜单项;

----②选择Debug面板,并在Category下拉列表中选择General;

----③在Executablefordebugsession框中输入或者寻找IIS执行文

件的路径(通常情况下位于WINNT\system32\inetsrv\inetinfo.exe);

----④在Programarguments框中输入-ew3svc,如图3所示;

图3 Debug面板设置

----⑤选择Link面板;

----⑥在Outputfilename框中输入被编译后的DLL将被放置的路径

和文件名。

这个路径必须位于Web服务器的根目录下或者某个

虚拟目标下,以便客户可以通过URL来访问。

例如,我们的Web

服务器的根目录是c:

\InetPub\wwwroot\,我们把helloweb.dll放置在该

目录下,这样客户就可以使用下面的URL来访问它:

----

----如果用户现在还没有退出登录以改变权限,请现在行动,

然后再登录回来。

----ISAPIExtensionWizard所产生的缺省代码已经包含了一个可

工作的ISA所需要的一切,虽然该ISA还没有任何功能,但我们

不妨先试着进行编译一下。

----按下F5键以运行ISA,如果弹出对话框问是否创建工程时

选择Yes。

几秒钟之后调试器就已经工作了,此时IIS应该运行

在后台。

现在一切就绪了,用户可以在自己喜欢的浏览器中

输入上面所提到的URL,并在最后面加上一个问号?

,如下所示:

----

----请注意把域名换成正确的值。

----第一次连接到ISA时可能要花几秒钟的时间,此后该DLL被

缓存到了内存中,连接速度就会显著提高。

当DLL被装入后,

在浏览器中应该显示如下信息:

----ThisdefaultmessagewasproducedbytheInternetServerDLLWizard.EdityourCHelloWebExtension:

:

Default()implementationtochangeit.

----我们的第一个ISA已经工作了。

----2.2分析源代码

----一个ISA包含两个主要组成部分:

解析映射表和命令处理函数。

----当一个请求来自EXTENSION_CONTROL_BLOCK(此结构用于在服务器

和ISA之间进行通信)时,它被传递到命令解析映射表。

解析映

射表由一些宏组成,如HelloWeb工程(HELLOWEB.CPP)中的:

BEGIN_PARSE_MAP(CHelloWebExtension,CHttpServer)

//TODO:

insertyourON_PARSE_COMMAND()and

//ON_PARSE_COMMAND_PARAMS()heretohookupyourcommands.

//Forexample:

ON_PARSE_COMMAND(Default,CHelloWebExtension,ITS_EMPTY)

DEFAULT_PARSE_COMMAND(Default,CHelloWebExtension)

END_PARSE_MAP(CHelloWebExtension)

----BEGIN_PARSE_MAP宏标志着解析映射表的开始,它以ISA的

CHttpServer类和基类作为参数;ON_PARSE_COMMAND宏则把一个特

定的请求或命令映射到一个命令处理函数中。

它的参数

包括命令处理函数名、函数的类以及请求的格式;

DEFAULT_PARSE_COMMAND宏确定了当请求为空或者与解析映射表

不匹配时调用的函数。

它的参数包括函数名和函数的类。

----命令处理函数是解析映射表中调用的主CHttpServer类的

成员函数。

下面就是HelloWeb工程中的Default命令处理函数:

voidCHelloWebExtension:

:

Default(CHttpServerContext*pCtxt)

{

StartContent(pCtxt);

WriteTitle(pCtxt);

*pCtxt<<_T("ThisdefaultmessagewasproducedbytheInternet");

*pCtxt<<_T("ServerDLLWizard.EdityourCHelloWebExtension:

:

Default()");

*pCtxt<<_T("implementationtochangeit.\r\n");EndContent(pCtxt);}

----当请求为空或者包含Default时此函数被调用。

首先它

通过参数得到请求的CHttpServerContext(命令处理函数的第

一个参数必须是一个CHttpServerContext),StartContent把

标志放到pCtxt中,然后WriteTitle放置

----2.3修改HelloWeb

----下面我们将把缺省的消息换成"我会编ISAPI程序了!

"。

----找到CHelloWebExtension类的成员函数Default,修改成如下形式:

voidCHelloWebExtension:

:

Default(CHttpServerContext*pCtxt)

{

StartContent(pCtxt);

WriteTitle(pCtxt);

*pCtxt<<_T("我会编ISAPI程序了!

");EndContent(pCtxt);}

----然后按照前面方法编译并运行该DLL,并在浏览器中重

装或者刷新URL,用户即可看到显示的消息已经变了。

----然而,如果用户看到"ServerError500:

Specifiedmodulenotfound."

这样的错误信息,则表示用户的工程是动态链接的,而所必需

的DLLs不存在。

为了修正这个错误,需要到Project菜单中选择

Settings命令,然后选择General面板,在MicrosoftFoundationClasses

下拉列表种选择UseMFCinaStaticLibrary,然后重新编译该工程。

----3.深入理解ISA编程

----3.1 进一步分析解析映射表

----在解析映射表中使用了五个宏:

----BEGIN_PARSE_MAP:

开始解析映射表的定义;

----ON_PARSE_COMMAND:

解析客户的命令;

----ON_PARSE_COMMAND_PARAMS:

把请求的数据映射到相应的数据结构中;

----DEFAULT_PARSE_COMMAND:

定义缺省命令;

----END_PARSE_MAP:

结束解析映射表的定义。

----我们在来看一看HelloWeb中的解析映射表:

BEGIN_PARSE_MAP(CHelloWebExtension,CHttpServer)

//TODO:

insertyourON_PARSE_COMMAND()and

//ON_PARSE_COMMAND_PARAMS()heretohookupyourcommands.

//Forexample:

ON_PARSE_COMMAND(Default,CHelloWebExtension,ITS_EMPTY)

DEFAULT_PARSE_COMMAND(Default,CHelloWebExtension)

END_PARSE_MAP(CHelloWebExtension)

----此映射表定义了两个命令:

一个空的请求和缺省的Default命令。

空的请求格式如下:

----

----它是由DEFAULT_PARSE_COMMAND宏处理的。

----然而,如果Default命令放在了问号的后面:

----

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1