Delphi环境下用Socket实现Web服务器

Delphi环境下用Socket实现Web服务器
Delphi环境下用Socket实现Web服务器

计算机应用

Delphi环境下用Socket

实现Web服务器

山东大学信息科学与工程学院(济南250100) 郑康锋 王秀娟 李 康

摘 要 Window s Socket规范是在Windows下进行网络通信编程的API接口,也是Window s 网络编程的事实标准。文章简要介绍了Socket原理、Delphi网络编程中的ServerSocket控件及HTT P协议,并给出了在客户机/服务器模型下用Delphi6.0实现Internet中常见的Web服务器实例。

关键词 WinSock Web服务器 H TTP协议 Delphi

1 概述

随着社会的不断发展,网络在社会信息化进程中扮演着日渐重要的作用。人们会经常遇到定期和不定期的将信息发布到Internet网上的问题。一般来讲,这个可以通过现在流行的Web服务器软件来解决问题。本文使用Delphi中的Socket控件编写了一个小型Web服务器,基本实现了信息发布的功能。

2 WinSock编程原理

Web服务器的原理就是基于Socket的编程。Socket接口是一种网络上跨平台的应用程序进程间通信机制,Window s Socket(简称WinSock)规范是一套开放的、支持多种协议的下Windows的网络通信编程的API接口,是Socket接口的重要扩充,也是Windows网络编程的事实标准。与BSD套接口相比,有如下一些新的扩充:

(1)异步选择机制

异步选择函数WSAAsyncSelect()允许应用程序提名一个或多个感兴趣的网络事件,当被提名的网络事件发生时,Window s应用程序的窗口函数将收到一个消息,这样就可以实现事件驱动了。

(2)异步请求函数

异步请求函数允许应用程序用异步方式获得请求的信息,如WSAAsy ncGetXByY()类函数。这些函数是对BSD标准函数的扩充。函数WSACancel AsyncRequest()允许用户中止一个正在执行的异步请求。

(3)阻塞处理方法

WinSock提供了 钩子函数负责处理Window s 消息,使Windows的消息循环能够继续。WinSock 提供了两个函数(WSASetBlockingH ook()和WSAUnhookBlockingH ook()),让应用程序设置或取消自己的 钩子函数。函数WSAIsBlocking()可以检测是否阻塞,函数WSACancelBlockingCall()可以取消一个阻塞的调用。

(4)错误处理

WinSock提供了两个WSAGetLastError()和WSASetLastError()来获取和设置最近错误号。

(5)启动和终止

由于Window s Sockets的服务是以动态链接库WinSock.DLL形式实现的,所以必须要先调用WSAStartup()函数对Window s Sockets DLL进行初始化,协商WinSock的版本支持,并分配必要的资源。在应用程序关闭套接口后,还应调用WSACleanup()终止对Window s Sockets DLL的使用,并释放资源,以备下一次使用。

在这些函数中,实现Windows网络实时通信的关键是异步选择函数WSAAsyncSelect()的使用。

3 Delphi中Socket控件的属性及方法

Delphi集成开发环境中提供了一些网络组件,其中的Socket组件类主要包括ClientSocket和ServerSocket控件,ClientSocket控件实现了客户应用程序的Socket的功能,ServerSocket控件实现了

!

电子技术?2002年第9期 中国传感器 http://w w https://www.360docs.net/doc/5a8983755.html,

服务应用程序的Socket的功能。这两个控件为套接字的直接使用提供了优秀的界面,实现了一些基层协议。本例中仅使用了ServerSocket控件,所以下面只给出了ServerSocket控件的属性及方法。3.1 主要属性

(1)Socket属性:代表了服务器端监听状态的Socket对象。

(2)Server Ty pe属性:用于确定服务器Socket 连接的两种工作方式:阻塞方式(StT hread Blocking),非阻塞方式(StNonBlocking)。在使用阻塞方式时,ServerSocket控件会自动为每一个新的Socket连接产生一个新的线程。在该线程处于读写状态的时候会被悬挂起来,直到所有的消息都被传送完毕。在使用非阻塞方式的时候,使用异步方式处理所有的读写操作。

(3)Active属性:属布尔类型。在应用程序运行过程中,通过Active属性可以确定Socket是否可以用于和客户应用程序进行通信。

(4)Port属性:属整数类型。服务器应用程序通过该属性确定Socket服务器的监视端口。

(5)T hreadCacheSize属性:用于确定允许的客户连接的最大线程数目。

3.2 主要事件

(1)Close事件:关闭Socket连接,并置Active 属性为False。

(2)Open事件:打开Socket连接,并置Active 属性为True。

(3)OnClientConnect事件:当服务器应用程序接收到客户应用程序的连接申请后,服务器Socket 控件将产生对该事件的响应。

(4)OnClientDisConnect事件:当与服务器应用程序通信的某一个客户应用程序关闭后,服务器Socket控件将产生对OnClientDisConnect事件的响应。

(5)OnClientRead事件:在服务器应用程序接收到客户应用程序的数据发生后产生。

(6)OnClientWrite事件:当服务器应用程序可以向客户应用程序发送数据时产生。

(7)OnClientError事件:在服务器应用程序建立和通信过程中,如果产生错误,则产生此事件。一般由客户应用程序响应和处理此事件。

(8)OnAccept事件:在当服务器应用程序接收到客户应用程序的连接申请后产生。

4 HTTP协议

Web服务器的通信是采用H TTP协议,HT TP 是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。H TTP/1.1的规范化工作正在进行之中。H TTP/1.0请求消息的格式为:

请求消息=请求行(通信信息|请求头|实体头)

CRLF[实体内容]

请求行=方法请求U RL H TTP版本号CRLF

方法=GET|HEAD|POST|扩展方法

U RL=协议名称+宿主名+目录与文件名请求行中的方法描述指定资源中应该执行的动作,常用的方法有GET、HEAD和POST。对一个繁忙的Web服务器进行采样,统计结果表明:500000个客户程序的请求中有99.68%是GET请求, 0.25%是HEAD请求,0.07%是POST请求。以下为请求数据包示例(Window s98,IE5.5为例): GET/index.htm HT T P.1.1

Accept:*/*

Accept L anguage:zh cn

Accept Encoding:gzip,deflate

U ser Agent:M ozilla/4.0(compatible;M SIE5.5;Windows 98)

Host:202.194.20.100:7809

Co nnection:K eep A live

以下为发送给客户的数据包示例:

HT T P/1.0200O K

Ser ver:M y W eb Serer/1.0

Date:Fr i,15M ar200220:26:12GM T

Co ntent t ype:text/html

Co ntent length:6789

##

其中:第一行表示应答成功,##表示发送的数据包内容,发送的内容与头信息之间必须空一行。

由此可知Web服务的过程:主机接收客户端(浏览器)的请求;分析信息;获取客户需要的文件;形成数据包;发送数据包给客户(浏览器);关闭与客户(浏览器)的连接。

5 Delphi中的程序实现

使用Delphi设计以上通信过程非常简单,主要是ServerSocket的相关事件驱动程序的程序编写。下面是实现Web服务器的部分主要源程序(内含简要功能说明,省略了变量的定义):

启动ServerSocket:

RootDir:=?C:\M y W eb?;//设置网页发布路径//

中国自动化 http://w w https://www.360docs.net/doc/5a8983755.html, !电子技术?2002年第9期

Default WebPage:=?default.htm?;//设置默认网页//

if ServerSocket.Active then

ShowM essage(?ServerSocket已经打开!?)

else

begin

try

Serversocket.Port:=80;//设置端口号//

Serversocket.Open;//打开服务器//

ex cept

ShowM essage(?端口被占用!?);

end;

end;

ServerSocket的ClientR ead过程:

HttpHead:=F ormat(?%s?,[?HT T P/1.0200O K?])

+#13+#10

+?Serv er:M y Web Server/1.0?+#13+#

10

+?Date:Fr i,15M ar200220:26:12GM T?

+#13+#10;{Http协议响应头信息} if GetT ype(Socket.ReceiveT ext,RequestFile)=?HEAD?then

begin//对H EAD请求的处理//

Socket.SendT ex t(HttpHead+#13+#10); Socket.Close;

end else

begin

SendFile(Socket);//对GET请求的处理//

Socket.Close;

end;

GetType函数:Input为接收到的请求信息, FileName为函数返回的文件名,函数返回值为H ttp 请求的方法Head或Get。

F irstOr der:=Copy(T rimL eft(Input),1,Pos(#13, T rimLeft(Input)) 1;//得到第一行//

i:=Pos(% ,FirstOrder);

Result:=A nsiUpperCase(copy(F irstO rder,1,i 1));//返回?GET?或?HEAD?//

FirstOrder:=Copy(FirstOrder,i+1,leng th(FirstOrder) i);

FileName:=Copy(FirstOrder,1,Pos(% ,FirstOrder) 1);

if(FileName=?/?)or(F ileName=?\?then

FileN ame:=F ileN ame+DefaultWebPag e;//返回文件名//

SendFile过程(入口为当前请求的Socket):

FileN ame:=Roo tDir+RequestF ile;//要发送的文件名// if not(FileExists(F ileName))then

begin

Socket.SendT ex t(?HT T P/1.0404N ot F ound?+#13 +#10+#13+#10);ex it;

end;

//获取文件类型//

RegF:=T Registry.Create;

RegF.RootK ey:=HKEY-CLA SSES-ROOT;

try

RegF.OpenKey(Ex tractF ileExt(FileN ame),False);

FileT y pe:=RegF.ReadString(?Content T y pe?);// FileT ype为从注册表中读出文件类型//

finally

RegF.CloseKey;

RegF.Free;

end;

M yF Stream:=T FileStream.Create(FileName,fmShare DenyN one);//创建文件流//

FileSize:=M yFstream.Size;//文件的大小//

Buffer:=PChar(A llocM em(FileSize+1));//创建缓冲区//

M yF Str eam.Seek(0,0);

M yF Str eam.Read(buffer^,FileSize+1);//将文件存入缓冲区//

M YF Str eam.F ree;

if F ileT ype<>%then//加上文件属性//

HttpHead:=HttpHead+?Content-type:?+F ile T ype+#13+#10;

HttpHead:=HttpHead+?Content-lengt h:?+Int

T oStr(F ileSize)+#13+#10

+#13+#10;

Socket.SendT ex t(HttpHead);//发送头信息//

for i:=0to(FileSize div8192) 1do//发送文件//

Socket.SendBuf(Buffer+i*8192)&,8192);

Socket.SendBuf((Buffer+(F ileSize div8192)* 8192)&,F ileSize mo d8192);

Fr eeM em(Buffer);

通过上述思路,作者设计出了一个简单的Web 服务器,方便的实现了信息发布,具有成本低、速度快等优点。该程序在Windows98/Windows2000, Delphi6.0上调试通过,系统性能较好。

参考文献

1 DOU GLAS https://www.360docs.net/doc/5a8983755.html, ER,DAV ID L.ST EVENS.Internet

w orking With T CP/I P Vol?:Client Server Prog ramming

A nd A pplication(Second Edition)

2 P.T hur rott,G.Brent,R.Bagdazian,S.T endon著,卢

庆龄,蒋全等译.Delphi3.0编程参考手册

3 鲍 敏,吴 昊等.Delphi网络高级编程.人民邮电出版

社2001年8月

4 窦万峰,张子瑜等.Delphi5功能解析.电子工业出版社

2000年4月

!

电子技术?2002年第9期 中国传感器 http://w w https://www.360docs.net/doc/5a8983755.html,

相关主题
相关文档
最新文档