📄 009.htm
字号:
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=GB2312"><TITLE>-->DELPHI专题--网络应用-->DELPHI与INTERNET(一)</TITLE>
<META NAME="keywords" CONTENT=" DELPHI专题--网络应用 DELPHI与INTERNET(一)">
<META NAME="description" CONTENT=" - DELPHI专题--网络应用 - DELPHI与INTERNET(一)">
<style>
<!--
#page {position:absolute; z-index:0; left:0px; top:0px}
.tt3 {font: 9pt/12pt "宋体"}
.tt2 {font: 12pt/15pt "宋体"}
a {text-decoration:none}
a:hover {color: blue;text-decoration:underline}
-->
</style>
</HEAD>
<a href="index4.html">返回</a>
<body text="#000000" aLink=#9900ff link=#006699 vLink=#006699 bgcolor="#FFFFFF" leftmargin="3" topmargin="3" marginheight="3" marginwidth="3">
<TABLE WIDTH="100%" CELLPADDING=10 CELLSPACING=0 BORDER=0>
<TR>
<TD class="tt2" bgcolor="#F5F8F8" width="84%"><center><B><FONT style="FONT-SIZE: 16.5pt" COLOR="#FF6666" FACE="楷体_GB2312">DELPHI与INTERNET(一)</FONT></B></center>
<hr color="#EE9B73" size="1" width="94%">
<p>这篇文章主要讲述如何使DELPHI和因特网配合工作。本文中将详述两个专门技术:
<br>
WININET:构建 FTP,HTTP 和 Gopher 用户端程序 ISAPI:扩充因特网信息服务,例如,获得服务器上的信息并把它们显示在浏览器上。
<br>
现今的计算机世界中,由于微软公司的因特网战略而掀起了一个巨大发展潮流。那些制作
<br>
CGI(公共网关接口)和第三方工具(即使是最基本的因特网工具)的日子将最终一去不复返了。对复杂的第三方工具的需求总是存在的,但现在程序员将会发现他们所需的大量的嵌入操作系统的因特网工具,简言之,并不需要进一步的投资,你就能够使用免费的DELPHI资源来:
<br>
<br>
*开发 WEB 浏览器 <br>
*运行 FTP,HTTP 和 Gopher ,在两个DELPHI应用软件之间或DELPHI应用软件和基于TCP
<br>
(传输控制协议)的服务器之间操作TCP <br>
因为DELPHI能够轻松地调用Windows API,并且它支持OCX/ActiveX,因此微软的新战
<br>
略和我们的计划配合的恰到好处。微软生产工具,而DELPHI程序员获得收成!<br>
<br>
在本篇中有些什么? <br>
<br>
这篇文章中包含了三个大部分和一些小部分,有三个大主题: <br>
*寻找资料:那里能搞到本文中提及的技术资料,而且包含了关于您所需的运行文中代码
的软硬件的简短说明。 <br>
*ISAPI:怎样使用ISAPI <br>
*WININET:怎样使用WININET <br>
<br>
在大多数情况下,本文中的ISAPI和WININET部分是完全独立的,您可以自由地选择阅读时的顺序。
<br>
<br>
查找资料,硬件和软件的要求 <br>
您需要一份Microsoft Windows NT 3.51 Server 或 NT 4.0 Server
的拷贝,其中应附有因特网信息服务文档,因为您需要甬道其中所提到的技术。这份文档应随NT
Server4.0 附送,NT 3.51的用户可从微软的网址上下载。运行Windows NT,您的机器的最低配置应为486兼容,20兆以上内存。<br>
您必须有另一台计算机装有网页浏览器。为使本文中的ISAPI部分能够顺利运行,第二台
<br>
机器必须能够运行所有支持网页浏览器的软件。如果在您的机器上运行的是Windows
95 或 Windows NT,那么本文中的WININET
代码片就能运行的最好。任何符合条件的网页浏览器在这种技术环境下都能够使用。
<br>
在1996年六月以后发布的Delphi2.0以上的版本中,有您所需的把Delphi连接到因特网上
<br>
的几乎全部资源。 <br>
如果您没有最新的Delphi版本[注:此处作者指的是2.0版本(译者)],那么您需要本文
<br>
档中提到的特殊文件,所有这些几乎都可以从万维网上免费获得[注:如果您正在使用Delphi2.0以上版本,则不许考虑(译者)]。所有本文中提到的技术在Delphi2.0环境下都能顺利工作,但在16位Delphi环境下则不一定能顺利工作。
<br>
如果您需要从万维网上下载信息,链接为:http://www.borland.com/TechInfo/delphi/i
<br>
ndex.html <br>
[注:现在已经不存在了!:-(( (译者)] <br>
Delphi2.0的新版本中附有 WININET.PAS
文档,如果你的拷贝中不包含它,那么上面那个 <br>
万维网节点可以为您提供。WININET.PAS包括为扩展微软视窗因特网所设计的变量清单、函数、类型和属性。这意味着您能够轻而易举地为您的应用程序增添FTP、HTTP和Gopher支持。微软公司的WININET.DLL是免费发布的,如果它不在您的Windows/System
或Windows/System32
目录下的话,您可以从微软公司那里得到它。下面是可获得WININET.H这个视窗帮助文件的万维网节点:
<br>
<br>
http://www.microsoft.com/intdev/sdk/docs/wininet/default.htm [注:好象也没了!: -(
(译者)] <br>
<br>
一般来说,微软因特网开发者的网上之家是微软节点的
INTDEV 部分。 <br>
除了WININET和ICP之外,另一个为Delphi支持的关键技术就是ISAP。正如微软公司文档中
<br>
所描述的,这项技术能使您“‘写入’服务器端的原本和过滤本,从而扩充微软因特网信息服务和其他ISAPI万维网服务”。
<br>
如果您需要找到关于ISAPI的描述,可以去: <br>
http://www.microsoft.com/intdev/sdk/servapi.htm [注:上帝保佑您!;-) (译者)]
<br>
在本文最后,附加了一个名为HTTPEXT.PAS的关键的ISAPI文档的拷贝。
<br>
微软公司免费发布的因特网控制包(ICP)是一个OCX/ActiveX控制集,您可以在Delphi中把它们拖放到应用程序上(Delphi2.0中包含这些控件)。他们提供了创建Delphi应用程序的即时支持,他们知道如何浏览网页、如何应用FTP、WINSOCK和其他因特网技术。如果您的Delphi拷贝中没有包含这些控件,那么您在使用它们之前您应该把这些文档添加进Delphi所在的目录中的Lib目录下。这些文档位于上面提及的链接中的Borland的INDEX.HTML站点下。在本文中我没有提到ICP控件,但是任何对这项技术有兴趣的人应该明确确认他拥有这些控件的拷贝。 <br>
您可以从我的站点下载我的Pascal应用文件,他们的名字是STRBOX.PAS
和 MATHBOX.PAS 。 <br>
经常察看一下这个站点上的关于本文提到的信息的更新情况是很有好处的。
<br>
在这里我假设读者对于Delphi和Object Pascal都很熟悉,并且读者对于因特网,HTML,
<br>
浏览器和万维网服务器有基本的了解。 <br>
<br>
<strong>ISAPI </strong><br>
<br>
ISAPI是一项很容易使用然而功能强大的技术,它能够让您扩充因特网信息服务的功能。
<br>
这项技术随WindowsNT 4.0附送,让您在您的服务器上建立WEB、FTP和GOPHER站点。同时这项技术与WindowsNT3.51
Server[注:指服务器版本,另一个版本是工作站版本(译者)]兼容。 <br>
在过去,扩充网页服务器的最佳办法是建立CGI应用程序。它们是强有力的工具,但是也
<br>
被他们的执行格式所限制[注:如PERL是解释执行的(译者)]。当您从浏览其上发出一个基于CGI的请求到服务器上时,这个CGI
应用程序将极有可能先被强制装入内存中,这会消耗很多时间。而且,在某些环境下,
CGI技术显得稍微难用了一点。 <br>
ISAPI是一种通过写入DLLs[注:动态链结程序(译者)]从而替代CGI应用的方法。您也可
<br>
以通过ISAPI来写过滤文本,但这项技术我不会在本篇中提及。同CGI相比,ISAPI更容易使用,而且它更快,同时能更好地利用系统资源。在下面几点中,我将详细地介绍为什么ISAPI DLLs比CGI应用要更为出色: <br>
ISAPI DLLs与HTTP服务位于相同的地址,因此他们能够从服务器上直接存取HTTP服务。与CGI应用相比,它们能更快地装入内存;当他们在服务器上发出请求时,所需的停悬的时间[注:指发出请求到接受服务器应答的时间(译者)]要少的多。这点当服务器的负荷很重时更加重要。
<br>
您可以控制DLLs何时被装载和卸载。例如:您可以在第一次尝试请求时预先装载DLLs;当它们不被使用时卸载 这个ISAPI应用DLLs以便释放系统资源。 <br>
正如前文所述,您可以利用ISAPI写过滤文本[注:一般指C/S结构中的脚本(译者)],更具微软的文档,您可以通过ISAPI过滤文本做下面这些事情: <br>
<br>
用户授权方案 <br>
压缩 <br>
加密 <br>
登入 <br>
通信分析或其他请求分析(例如,寻找 "..\..\etc\password"
中的请求) <br>
<br>
在本文中,我会着重介绍如何编写返回数据集的DLLs,或者是如何与运行浏览器的用户进
<br>
行简单的联系。 <br>
<br>
<strong>ISAPI 基础 <br>
</strong><br>
HTTPEXT.PAS文件包含了使用ISAPI的关键声明。这个文件应随1996年6月以后发表的
<br>
Delphi版本分发。它也可以在Borland的站点上找到,在本文的ISAPI部分附有这份文档。因为这是基于NT的技术,
您必须使用Delphi2.0以上的版本来应用这项技术。您不可能在16位的编辑器上应用它。
<br>
HTTPEXT.PAS包含了微软公司创立的ISAPI技术的接口[注:指Delphi接口,ISAPI由C++编写(译者)]。在编写Delphi的时候并没有提供ISAPI的用户接口,我会仅仅就如何使用微软公司的现有技术进行描述。不过,ISAPI
太容易使用了,而且对大多数用户来说,用户的Delphi对象的版本并不是必须的。<br>
有三个函数可作为ISAPI DLLs的入口,前两个是必须的,第三个时可选的。
<br>
<br>
GetExtensionVersion: 进对最低版本做检查 <br>
HttpExtensionProc: 这是DLL的入口,就象是Delphi应用程序中的 begin...end 块 <br>
TerminateExtension:
这是个可选的程序,它可以用作清除其他内存分配的线程。 <br>
<br>
当您在创建ISAPI DLL的时候,您必须引用上面列出的三个函数中的头两个函数,执行这
<br>
两个函数是所有ISAPI编程的关键。 <br>
这三个语句都包含了“字输出”,使用这项术语是因为ISAPI DLLs扩充了因特网信息服务
<br>
器。(记住,因特网信息服务器指的是微软服务器。如果您要把一台NT服务器作为体格网页服务器的话,那么,这正是您所需的工具。ISAPI
DLLs随NT4.0分发,在安装操作系统是自动安装。) <br>
ISAPI提供了一个制作服务器可遵循的标准。例如,它可以把网景公司的复杂的NSAPI接口
<br>
压缩至相关的简练而优美的ISAPI来对NSAPI接口进行操作。 <br>
下面是这两个重要函数的声明 <br>
<br>
function GetExtensionVersion(var Ver: THSE_VERSION_INFO): BOOL; stdcall; <br>
function HttpExtensionProc(var ECB: TExtensionControlBlock): DWORD; stdcall; <br>
<br>
您只要把GetExtensionVersion粘贴到您的DLLs救行了.当ISAPI向公众发布新版本时您只需要做轻微的改动。
<br>
<br>
function GetExtensionVersion(var Ver: THSE_VERSION_INFO): <br>
BOOL; stdcall; <br>
begin <br>
Ver.dwExtensionVersion := $00010000; // 1.0 support <br>
Ver.lpszExtensionDesc := 'Delphi 2.0 ISAPI DLL'; // Description <br>
Result := True; <br>
end; <br>
<br>
The parameter passed to this function is declared in HTTPEXT.PAS as follows: <br>
有关的参数在HTTPEXT.PAS中声明如下: <br>
<br>
PHSE_VERSION_INFO = ^THSE_VERSION_INFO; <br>
THSE_VERSION_INFO = packed record <br>
dwExtensionVersion: DWORD; <br>
lpszExtensionDesc: array[0..HseMaxExtDLLNameLen-1] of Char; <br>
end; <br>
<br>
常量HseMaxExtDllNameLen 在声明中的值为256。纪录中的这两个变量是“自声明”的,
前一个包含了ISAPI的版本号[注:即变量dwExtensionVersion (译者)],后一个则表示用户定义的一个用来描述DLLs的字符串。
<br>
在您引用GetExtensionVersion语句的同时,您必须在您的DLL程序的DPR文件部分增添输
<br>
出部分。在您写这段语句时您还应该写下: <br>
<br>
exports <br>
GetExtensionVersion, <br>
HttpExtensionProc; <br>
<br>
这就是您在建立这两个重要ISAPI DLL的函数时所要做的。下一步,使用
HttpExtensionProc,稍微复杂一点,因此我将把它作为一个独立的部分。 <br>
<br>
与 HttpExtensionProc 一起工作 <br>
<br>
HttpExtensionProc语句是DLL的入口。它的作用就好比C语言中的
main() 语句,或者 <br>
Delphi 中的begin...end 部分<br>
<br>
这里有一个简单的使用GetExtensionVersion语句的例子 <br>
<br>
function HttpExtensionProc(var ECB: TExtensionControlBlock): <br>
DWORD; stdcall; <br>
var <br>
ResStr: string; <br>
StrLen: Integer; <br>
begin <br>
ECB.lpszLogData := 'Delphi DLL Log'; <br>
ECB.dwHTTPStatusCode := 200; <br>
ResStr := '<HTML><TITLE>Test server result</TITLE>' + <br>
'<H1>Test server results</H1>' + <br>
'<BODY>Hello from ISAPI<BR></BODY>' + <br>
'</HTML>'; <br>
<br>
ResStr := Format( <br>
'HTTP/1.0 200 OK'#13#10+ <br>
'Content-Type: text/html'#13#10+ <br>
'Content-Length: %d'#13#10+ <br>
'Content:'#13#10#13#10'%s', [Length(ResStr), ResStr]); <br>
<br>
StrLen := Length(ResStr); <br>
ECB.WriteClient(ECB.ConnID, Pointer(ResStr), StrLen, 0); <br>
Result := HSE_STATUS_SUCCESS; <br>
end; <br>
<br>
如果您在浏览其中向这个DLL发出请求,那么您会得到一页这样的回应:
<br>
<br>
Test Server Results <br>
Hello from ISAPI <br>
<br>
函数体内的大部分域提供基本信息的简单的HTML代码密切相关。您还需要填写TExtensionControlBlock中的一些域,如下所示。<br>
注意到在这个纪录里有一个叫做WriteClient的函数指针,您可以引用这个函数把信息传
<br>
送回浏览器。当呼叫这个函数时,您使用到了下面提到的TExtensionControl块中的ConnID字段。当函数被呼叫时,ConnID为您自动填充。
<br>
在察看函数的代码之前,请让我为您演示所有用到的上文提及的HttpExtensionProc函数
<br>
的ISAPI DLL的完整程序<br>
<br>
library Isapi1; <br>
library Isapi1; <br>
<br>
uses <br>
Windows, SysUtils, HTTPExt; <br>
<br>
function GetExtensionVersion( var Ver: THSE_VERSION_INFO ): BOOL; stdcall; <br>
begin <br>
Ver.dwExtensionVersion := $00010000; // We're expecting version 1.0 support <br>
Ver.lpszExtensionDesc := 'Written in Delphi 2.0'; <br>
Result := True; <br>
end; <br>
<br>
function HttpExtensionProc( var ECB: TEXTENSION_CONTROL_BLOCK ): DWORD; <br>
stdcall; <br>
var <br>
ResStr: string; <br>
StrLen: Integer; <br>
begin <br>
ECB.lpszLogData := 'Delphi DLL Log'; <br>
ECB.dwHTTPStatusCode := 200; <br>
ResStr := ' <br>
' + <br>
' <br>
Test server results <br>
' + <br>
' <br>
Isapi says hello to DevRel <br>
<br>
'; <br>
ResStr := Format( <br>
'HTTP/1.0 200 OK'#13#10+ <br>
'Content-Type: text/html'#13#10+ <br>
'Content-Length: %d'#13#10+ <br>
'Content:'#13#10#13#10'%s', [Length(ResStr), ResStr]); <br>
StrLen := Length(ResStr); <br>
ECB.WriteClient(ECB.ConnID, Pointer(ResStr), StrLen, 0); <br>
Result := HSE_STATUS_SUCCESS; <br>
end; <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -