admin 管理员组

文章数量: 887053


2023年12月24日发(作者:bootstrap版本)

第一章 概述

如今,上网已成为最热门话题,通过Internet,我们既能获取信息又能发布信息,而迅速发展的Web技术更是给Internet应用提供了一个很好的发展方向。当今的许多应用都是基于web技术的,如电子商务、视频会议、远程医疗诊断等。由于HTMI 语言的标准统一性,只要在设备里建立一个微型web服务器,人们就可以使用现有的Web浏览器与该设备进行双向交互、接收或发送信息。因此,针对微型web服务器的研究和应用,具有重大的意义,它为我们管理、控制和监测各种各样的设备提供了一个很好的途径一基于Internet,也就是说,只要设备接入了Internet,我们就可以在世界上的任何地方十分方便地控制、操纵那些配备有微型Web服务器的设备。

1.1 课题意义、目的

WWW 是 World Wide Web (环球信息网)的缩写,也可以简称为 Web,中文名字为“万维网”。它起源于1989年3月,由欧洲量子物理实验室 CERN(the European Laboratory for

Particle Physics)所发展出来的主从结构分布式超媒体系统。通过万维网,人们只要通过使用简单的方法,就可以很迅速方便地取得丰富的信息资料。 由于用户在通过 Web 浏览器访问信息资源的过程中,无需再关心一些技术性的细节,界面简单容易操作。长期以来,人们只是通过传统的媒体(如电视、报纸、杂志和广播等)获得信息,但随着计算机网络的发展,人们想要获取信息,已不再满足于传统媒体那种单方面传输和获取的方式,而希望有一种主观的选择性。现在,网络上提供各种类别的数据库系统,如文献期刊、产业信息、气象信息、论文检索等等。由于计算机网络的发展,信息的获取变得非常及时、迅速和便捷。

到了1993年,WWW 的技术有了突破性的进展,它解决了远程信息服务中的文字显示、数据连接以及图像传递的问题,使得 WWW 成为 Internet 上最为流行的信息传播方式。 现在,Web 服务器成为 Internet 上最大的计算机群,可以说,Web 为 Internet 的普及迈出了开创性的一步, WWW 采用的是客户/服务器结构,其作用是整理和储存各种WWW资源,并响应客户端软件的请求,把客户所需的资源传送到Windows NT、UNIX 或 Linux 等平台上。

国际计算机互联网也称因特网(Internet),已有20多年的发展历史,它的前身是美国国防计算机互联网(ARPA),现已发展为一个全球性的计算机互联网络。该网是世界上信息资源最丰富的计算机网络,被人们公认为是未来国际信息高速公路的雏形。 因特网上具有上万个技术资料数据库,其信息媒体包括数据、图象、文字、声音等多种形式;信息属性有数据、交换软件、图书、档案等门类;信息内容涉及通信、计算机、农业、生物、天文、医学、政治、法律、军事、音乐等各个方面。

可以看出万维网是Internet的一部份

实际上,WWW( World Wide Web ) 是一种建立在Internet上的全球性的、交互的、动态、多平台、分布式、图形信息系统。它只是建立在Internet上的一种网络服务。它的开发最初是为了在科学家之间共享成果, 科学家们可以将科研成果以图文形式方在网上进行共享。它的最基本的概念就是Hypertext(超文本),如果你用过Windows上的任何一种在线帮助

系统你就会比较了解它的结构了。 现在,WWW的应用已远远超出了原设想,成为Internet

上最受欢迎的应用之一。它的出现极大地推动了Internet的推广。

下图显示了星型和拓扑的网络连接:

本次设计就是需要完成一个简易的WEB服务器的设计,实现web服务器基本功能:

页面访问请求响应、HTML文件的解析以及数据发送。所以在完成设计之前,必须先了解WEB服务器设计的原理与结构

1.2 WEB服务器现况

目前在市场上有20到30种Web应用服务器,每种服务器在实现对象组件支持、 分布式计算、部署的速度和易用程度上采取了不同方式。

目前市场上主流Web服务器主要有以下几种产品:

1.Apache,由SUN公司开发的Apache服务器可以运行在包括Linux等多种系统平台之上。Apache支持许多特性,大部分通过编译的模块实现,如很有用的URL重写,定制日志文件以及过滤支持等。

2.Zeus Webserver3.3.8 服务器,Zeus服务器在SMP (Symmetric Multi Processing的简称,意为对称多处理系统,内有许多紧耦合多处理器,这种系统的最大特点就是共享所有资源) 环境下有优秀的可伸缩性,并实现了常见的特性集合,如访问控制、动态内容产生和安全等。

3. iPlanet Enterprise Edition 4.1,Netscape公司开发的iPlanet具有现今高性能WEB服务器的特性,如具有很高的可靠性、可用性、可维护性,系统高度可扩展性等特点,相对其它WEB服务器iPlanet还提供更多的JAVA功能。

4.AOLserver 3.3.1 ,AOL公司开发的AOLserver 3.3.1是一个多线程、可升级和扩展的WEB服务器。

5. Roxen WebServer 2.1.31,在Roxen中可以使用RXML语言生成动态网页内容。RXML是函数形式的服务器端XML脚本语言,它由Roxen服务器解析并执行。

6. Jigsaw,它由WWW组织(W3C)开发,W3C组织负责研究和规定网络协议的标准(如HTTP)。它使用JAVA语言开发,是成功的面向对象、功能全面的服务器。因为Jigsaw不受测试平台的限制,所以Jigsaw是一个具有活力的、拥有无限潜能的优秀WEB服务器。

在嵌入式系统的应用中,由于HTMI 语言的标准统一性,只要在设备里建立一个微型web服务器,人们就可以使用现有的Web浏览器与该设备进行双向交互、接收或发送信息。它为我们管理、控制和监测各种各样的设备提供了一个很好的途径,只要设备接入了Internet,我们就可以在世界上的任何地方十分方便地控制、操纵那些配备有微型Web服务器的设备。

在Internet上为了发布信息,用户必须运行Web服务器程序。但现成的服务器程序有时候不能满足所有人的要求,所以可以动手开发一个自己的Web服务器程序,其功能就可由设计者定制的功能和需求决定了。

1. 3 解决方案和所做主要工作

本次设计就是需要完成一个简易的WEB服务器的设计,实现web服务器基本功能:

页面访问请求响应、HTML文件的解析以及数据发送。所以在完成设计之前,必须先了解WEB服务器设计的原理与结构。

一般来说,Web服务器通常由以下几个部分组成:(1)服务器初始化部分.这部分主要完成Web服务器的初始化工作,如建立守护进程、创建TCP套接字、绑定端口、将TCP套接字转换成侦听套接字,进入循环结构,等待接收用户浏览器连接.(2)接收客户端请求.由于客户端请求以文本行的方式实现,所以服务器一般也以文本行为单位接收.(3)解析客户端请求.这部分工作比较复杂,需要解析出请求的方法、URL目标、可选的查询信息及表单信息.如果请求方法为HEAD,则简单地返回响应首部即可;如果方法是GET,则首先返回响应首部,然后将客户端请求的URL目标文件从服务器磁盘上读出,再发送给客户端。 (4)发送响应信息之后,关闭与客户机的连接.

在了解WEB服务器的基本结构后,就需要更进一步了解如何实现服务器与协议的连接,那就需要用到CSOCK,这也是本次设计中的核心与重点。通过SOCKET,利用VC++编程就能基本实现了简易的WEB服务器的设计,并能在window系统下运行良好的运行,实现web服务器基本功能:页面访问请求响应、HTML文件的解析以及数据发送。

第二章 WEB服务体系结构

2.1 WEB服务器基本构架

Web应用的基本构架包括浏览器、网络和Web服务器。浏览器向服务器请求Web页,Web页可能包括由浏览器解释执行的客户端脚本,而且可以与浏览器、页内容和页中包含的其他控件(Java Applet、ActiveX控件和插件等)进行交互。用户向Web页输入信息或通过超级链接导航到其它Web页,与系统进行交互,改变系统的“业务状态”。

2.1.1 WEB服务器和浏览器

WEB 是基于请求和响应的系统,它是在C/S(Client/Server)结构的基础上发展而来

的。为了实现世界范围内的信息共享和发布,它规范了通讯协议,并规范、强化Client/Server两端的系统功能,WEB为用户在Internet上查看文档提供了一个图形化的,易于进入的界面,WEB是一种基于超文本传输协议(Hypertext Transport Potocol 简称HTTP)向计算机传送多媒体信息(如文本、图片、声音、视频、交互式应用程序)的Internet服务。同C/S结构一样,WEB由两部分构成,即WEB服务器端和WEB浏览器端,WEB服务器的主要功能是:创建、管理和维护WEB页面,对浏览器的请求进行应答并返回HTML页,WEB浏览器(Browser)用来观看WEB资源的客户端软件,主要负责请求,解释并显示WEB页,其工作过程见图2.1。

Web浏览器通常可以使用流行的IE或者其它的浏览器。服务器端的TCP/IP协议是操作系统内嵌的,其信息流符合HTTP协议。服务器中的HTTP引擎用来分析浏览器的请求消息,并根据请求做出相应的动作。这些动作包括向浏览器发送一些静态页面或调用一些应用服务程序。对于服务器中的静态web页面,可以使用一些常用软件如FrontPage等制作,以备Web服务器调用。而服务器中的应用服务程序则用来扩展服务器所提供的服务。从图l中可以看出,微型web服务器的核心就是:HTTP引擎。

HTTP协议是一种网络应用层的标准协议,Web浏览器和Web服务器之间的通信都是采用HTTP协议来实现的。因此只要是符合HTTP协议的通讯过程和数据内容,就可以使用浏览器作为客户端进行连接和传递。

图2.1 Web工作原理

图2.1 主要过程为:

(1) WEB浏览器通过将URL发给WEB服务器请求信息;

(2) WEB服务器响应请求,并返回给客户机超文本标记语言(HTML)页面;

(3) WEB浏览器对超文本标记语言(HTML)页面进行解释并显示。

客户机 服务器

Web浏览器

请求服务

…………

………….

Web服务器

Internet或Intranet

2.1.2 WEB页面

WEB页面是WEB系统实现发布、进行管理的主要对象。WEB页面像一个大的容器,将要发布的文字、图片、声音、动画、视频等多种媒体信息封装到一起,供WEB系统实现发布,进行管理。对于WEB系统而言,在众多的WEB页面中,有一个称为WEB主页的页面,它是访问者浏览WEB系统的起点。每个WEB页面都具有唯一的地址,称为统一资源定位符(URL),URL由存储此页面的计算机名和此页面的确切路径构成。

WEB页面是超文本标记语言(HTML)编写的。HTML是一种嵌入式语言,通过在普通文本中嵌入各种标记(TAG),使普通文本具有了超级文本的功能。根据WEB页面的内容,可将WEB页面分为三种类型:静态页面,动态页面,目录列表页面。

2.2 WEB系统的基本原理是请求/响应

客户端,浏览器接受用户输入的网页地址(URL)并进行分析,从而得到网页的文件名字和存放网页的计算机地址以及服务程序的端口号,首先根据计算机地址及端口号与服务器建立连接,然后把网页名称及浏览器本身的有关信息按照一定的格式组织起来,发给服务器,这就是‘请求’。比如用户输入/,从而可知:

(1) 计算机名称为根据这个名字能获知其计算机地址

(2) 端口号为80(http服务的默认端口号)

(3) 页面的文件名为

浏览器就与kulin上端口号为80的服务程序建立连接,并把类似下面的数

据发过(作为服务‘请求’):

GET / HTTP/1.1

Accept:image/gif,image/x-xbitmap,application/-powerpoint,*/*

Accept-Language:ch

UA-pixels:800*600

UA-color:color16

UA-OS:Windows xp

UA-CPU:P41.6

User-Agent:Mozilla/2.0(compatible’MSIE3.01;Window XP

Host:

Connection:Keep-Alive

其中第一行说明了文件名称()、请求的类型(GET)及浏览器支持的协议版本(HTTP/1.0)

服务器端接受到请求后,对其进行分析,解析出网页的文件名称及其他信息(比如请求的类型、处理要求等),根据网页的文件名称到磁盘上提取文件内容,把文件内容和一些必要的说明信息打包后发给浏览器,然后断开连接,这就是“响应”。(浏览器接到文件内容后就将其中的内容显示出来了)比如对于文件长度为2559B的来说,可以发送如下数据作为“响应”:

HTTP/1.1 200 OK

Server: -HttpSvr/1.1

Date:WED,20 may 2006 12:45:21

Content-type:text/html

Content-length:2559

Last-Modified:Sun,22 may 2006 14:21:50

<接下来是的文件内容>

上述数据分2大部分,第1部分为“头”,其中,第1行是状态行,包括服务器执行的HTTP版本及本次响应的状态码。后4行分别说明了服务器名称、当前日期、数据类型、数据长度、最后修改的日期和时间。第2部分为数据“体”,是“请求”要求传送的数据,它跟在1个空行之后。

当然,客户端和服务器之间还可能有一些中间环节,比如代理服务器、网关、“隧道”等,在此我们先不予考虑。

2.3 WEB服务器/浏览器的通信

要完成Web服务,除了网络通信链路的建立和拆除,之外至少还要有二方面的功能:“分折请求” 和“构造响应”。客户端与服务器交换数据之前,首先用TCP/IP建立连接,客户端向服务器请求数据,服务器则向客户端响应并提供数据.客户端和服务器以HTTP协议进行请求和响应.服务器和客户端只能为一次事务处理建立并维持连接,完成一次事务处理后便结束连接.

每一个客户端向服务器发送请求均以方法(Method)开始,后跟对象的URL.客户端一般要在上述信息中补充所采用HTTP协议的版本号,其后跟一个回车换行(CRLF)字符对.依据请求情况,浏览器可能在CRLF后加上浏览器按特别的首部格式编码的信息.完成后,浏览器给请求加上一个CRLF.还可依据请求情况,把一个实体(MIME格式文档)加到整个请求之后.一个HTTP方法实际上是一条命令,客户端用它来说明其请求目的,常用的有GET,HEAD和POST.

Web服务器收到请求并解析之后,以一个HTTP响应消息响应客户端的请求.这个响应消息通常以HTTP协议版本号开始,后面是三位状态码和一个原因短语(Reason phrase),其后是一个CRLF,再后是请求的信息(它被服务器以一种特殊的首部格式编码),最后,服务器加上一个CRLF.其后还可以有一个可选实体.状态码是三位数,它描述了服务器理解和满足请求的情况,原因短语是状态代码的一个简短说明.HTTP协议版本号、状态代码、原因短语一起构成了状态行.

上述分析不难看出,接收客户端请求、解析客户端请求、响应客户端请求、向客户端回送请求的结果是Web服务器所需完成的主要任务,Web服务器程序代码主要是为了完成这几项任务.

2.3.1 分析请求

如前文所述,“请求”的第1行数据是最重要的,它的格式是:

方法 资源地址 HTTP版本号 回车换行

“方法”主要有3种:

GET:要求必须返回一定的内容。有时还必须根据“请求”的要求先对内容做一定的处理(比如解压缩或根据时间进行过滤)。

HEAD:处理办法和GET完全相同,但要求只返回“头”,而不可返回任何实质内容(“体”)。

POST:用来处理网页的附属内容,比如“注解”、数据回送等。

作为简单的服务器,我们只考虑第一行,且只处理GET请求,版本号不予理睬。

2.3.2构造响应

如前文所述,响应的第1行是状态行,非常重要,格式如下:

HTTP 版本号 状态码 状态文字说明 回车换行

版本号可取HTTP/1.1;状态码是3位数字,根据情况按表2.1所示代码取值。

表2.1 状态码值

代码特征 含义

1 开头的 保留未用

2 开头的 成功

4开头的 客户断错误

5开头的 服务器端错误

作为简易的服务器,“响应”可以只返回状态行和文件内容,即送回如下的内容:

HTTP/1.1 200 OK 状态行

一个空行

文件内容 文件内容

举例

比如200表示处理成功

比如400表示“请求”有错,

404表示找不到客户指定的文件

3开头的 需要进一步处理

2.4 Winsock技术简介

套接字是网络通信的基本构件,提供了不同主机间进程双向通 信的端点,如同电话,只有当一方拨通另一方时,双方方能建立对话,而套接字正好比双方的电话。通过Sockets 编程,程序可以跳过复杂的网络底层协议和结构,直接编制与平台无关的应用程序。随着Internet 的广泛应用,Sockets 已逐渐成为网络编程的通用接口。

因为Windows Sockets 主要是面向C/S 体系结构的,即客户向服务器发出请求,服务器只有在接收到请求后才能提供相应服务。双方在建立对话前, 服务进程和接受服务的进程( 客户)必须首先建立起各自用于网间进程通信的半相关,即一个三元组( 协议,本地地址,本地端口),但只有双方独立的半相关还不能建立起沟通。一个完整的网络通信进程必须通过由两个独立进程组成的一个完整的全相关唯一确定方能得已实现,而且,只有两个性质相同的半相关才能建立一个完整的全相关五元组— —(协议,本地地址,本地端口,远

地地址,远地端口),由此方能建立起一个网间进程通信的实例。

2.4.1 什么是Windows Sockets规范?

Windows Sockets规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程上的标准。

Windows Sockets规范是建立在Bekeley套接口模型上的。这个模型现在已是TCP/IP网络的标准。Windows Sockets规范是以U.C. Berkeley 大学UNIX中流行的Socket接口为范例而设定的一套Windows网络接口编程。这个规范不仅包含了我们所熟悉的Berkeley

Socket套接口风格的库函数,也包含了针对Windows的扩展库函数,这样一来使程序员能充分利用Windows消息驱动机制进行相应的编程。

应用程序调用Windows Sockets的API实现相互之间的通讯。Windows Sockets又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。它们之间的关系如图2.2。

应用程序1

应用程序2 应用程序n

网络程序设计,如Winsock等

网络通讯协议,如TCP/IP

操作系统,如Windows

物理通讯介质

图2.2 应用程序与sockets的关系

2.4.2 Windows Sockets规范发展历程

indows Sockets规范发展至今已经经历了三个阶段,首先是Windows Sockets1.0的发布,Windows Sockets 1.0代表了网络软件供应商和用户协会细致周到的工作的结晶。Windows Sockets 1.0规范的发布是为了让网络软件供应商和应用程序开发者能够开始建立各自的符合Windows Sockets标准的实现和应用程序。

为了更能满足个系统的要求,有发布了之后的1.1版本Windows Sockets 1.1继承了Windows Sockets 1.0的准则和结构,并且仅在一些绝对必要的地方作了改动。这些改动都是基于不少公司在创作Windows Sockets 1.0实现时的经验和教训的。Windows Sockets 1.1包含了一些更加清晰的说明和对Windows Sockets 1.0的小改动。还有很多的改动就不做一一介绍了。

现在大多的网络编程的规范已经是Windows Socket 2,它在1.1上又有了更多的改动,具体的改动在这里也不做具体的介绍了。

2.4.3 套接口

套接口是从英文单词socket翻译过来的,它是网络通信的基本构件。套接口是可以被命名和寻址的通信端点,使用中的每一个套接字都有它的类型和一个与之相连的进程。

套接口存在于通信区域中。通信区域也叫地址族,它是一个抽象的概念,主要用于将通过套接口通信的进程的共有特性综合在一起。套接口通常和同一个域中的套接口交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。Windows Sockets规范支持单一的通讯域,即Internet域。各种进程使用这个域互相之间用Internet协议族来进行通讯(Windows Sockets 1.1以上的版本支持其他的域,例如Windows Sockets 2)。

套接口可以根据通讯性质分类;这种性质对于用户是可见的。应用程序一般仅在同一类的套接口间通讯。不过只要底层的通讯协议允许,不同类型的套接口间也照样可以通讯。用户目前可以使用两种套接口,即流套接口和数据报套接口。流套接口提供了双向的,有序的,无重复并且无记录边界的数据流服务。数据报套接口支持双向的数据流,但并不保证是可靠,有序,无重复的。也就是说,一个从数据报套接口接收信息的进程有可能发现信息重复了,或者和发出时的顺序不同。数据报套接口的一个重要特点是它保留了记录边界。对于这一特点,数据报套接口采用了与现在许多包交换网络(例如以太网)非常类似的模型。

2.5 VisualC++6.0简介

Visual C++是运行于Windows平台上的交互式的可视化集成开发环境,它是美国Microsoft公司开发的Microsoft Visual Studio套件的一部分。跟其他的可视化集成开发环境(如Visual Basic、Delphi、C++ Builder)一样,Visual C++ 6.0集程序的代码编辑、编译、连接和调试等功能于一体,给编程人员提供了一个完整方便的开发界面和许多有效的辅助开发工具。Visual C++ 6.0的应用程序向导可以为很大一部分类型的程序提供框架代码,用户不用书写程序代码,只需按几个按钮就可以生成一些完整的可以运行的程序。

第三章 系统设计

3.1 界面设计

正如包装那样,一个优秀的软件除了方便实用的功能外,其界面的优秀设计也是必不可少的,因为良好的界面形象一来能够体现公司的形象和实力;二来能够使用户操作更为方便,

具有说明性的图表按钮也能够为用户带来使用的方便;三来能够体现其软件的良好特性和功能。

目前软件界面的发展潮流为图形说明化和具体化,以前简单和粗糙的简单设计已经逐渐被淘汰,典型的如WindowsXP,其界面和Windows2000就有明显的差别,图形化的成分更多了,细致到每一个图表都有其特定的功能含义。

本次设计的WEB服务器端的程序软件,虽然小,但也要尽量按照软件界面设计的发展趋势来完成,首先要方便简洁,另用户能很容易的上手操作,其次要尽量体现软件的良好特性和功能。

3.1.1界面设计要求

对于应用软件来说,一个基本现实就是:用户界面是面向用户的。用户需要的是开发者开发的应用软件满足其需求,并且易于使用。界面设计的重要性有这么几个原因:首先,用户界面越直观,就越易用,越易用就越便宜。因为界面越好,培训用户就越容易,降低了培训成本;界面越出色,用户就越少求助,降低了客户支持成本。其次,界面越出色,用户就喜欢使用,增强了开发者工作的满意度。

3.1.2界面制作方法

该WEB服务器是通过C++编程来实现的。首先新建一个MFC Appwizard(exe)工程,然后建立一个对话框。接着在对话框里面添加按钮,列表框以及静态文本框,改变各控件的名称,调整对话框及各控件的大小,使界面美观大方。

3.2 侦听模块设计

侦听模块是HTTP服务器很重要的模块之一,它包括了服务器端的操作套接字,帮定端口,监听客户端请求几个部分,是服务器运行的关键部分。它的流程图如下:

返回错误

侦听模块流程图

达到最大建立监听队列,设置最大连接数

没达到最大数

accept()函数

绑定端口

请求

客户端

建立监听Socket

初始化WinSock

3.2.1服务器端操作Socket(套接字)

(一)在初始化阶段调用WSAStartup()

此函数在应用程序中初始化Windows Sockets DLL,只有此函数调用成功后,应用程序才可以再调用其他Windows Sockets DLL中的API函数。在程序中调用该函数的形式如下:WSAStartup((WORD)((1<<8|1),(LPWSADATA)&WSAData),其中(1<<8|1)表示我们用的是WinSocket1.1版本,WSAata用来存储系统传回的关于WinSocket的资料。

(二)建立Socket

初始化WinSock的动态连接库后,需要在服务器端建立一个监听的Socket,为此可以调用Socket()函数用来建立这个监听的Socket,并定义此Socket所使用的通信协议。此函数调用成功返回Socket对象,失败则返回INVALID_SOCKET(调用WSAGetLastError()可得知原因,所有WinSocket 的函数

都可以使用这个函数来获取失败的原因)。

SOCKET PASCAL FAR socket( int af, int type, int protocol )

参数: af:目前只提供 PF_INET(AF_INET);

type:Socket 的类型 (SOCK_STREAM、SOCK_DGRAM);

protocol:通讯协定(如果使用者不指定则设为0);

如果要建立的是遵从TCP/IP协议的socket,第二个参数type应为SOCK_STREAM,如为UDP(数据报)的socket,应为SOCK_DGRAM。

(三)绑定端口

接下来要为服务器端定义的这个监听的Socket指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。

int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR *name,int namelen );

参 数:s:Socket对象名;

name:Socket的地址值,这个地址必须是执行这个程式所在机器的IP地址;

namelen:name的长度;

如果使用者不在意地址或端口的值,那么可以设定地址为INADDR_ANY,及Port为0,Windows Sockets 会自动将其设定适当之地址及Port (1024 到 5000之间的值)。此后可以调用getsockname()函数来获知其被设定的值。

(四)监听

当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。listen()函数使服务器端的Socket 进入监听状态,并设定可以建立的最大连接数(目前最大值限制为 5, 最小值为1)。该函数调用成功返回0,否则返回SOCKET_ERROR。

int PASCAL FAR listen( SOCKET s, int backlog );

参 数: s:需要建立监听的Socket;

backlog:最大连接个数;

服务器端的Socket调用完listen()后,如果此时客户端调用connect()函数提出连接申请的话,Server 端必须再调用accept() 函数,这样服务器端和客户端才算正式完成通信程序的连接动作。为了知道什么时候客户端提出连接要求,从而服务器端的Socket在恰当的时候调用accept()函数完成连接的建立,我们就要使用WSAAsyncSelect()函数,让系统主动来通知有客户端提出连接请求了。该函数调用成功返回0,否则返回SOCKET_ERROR。

int PASCAL FAR WSAAsyncSelect( SOCKET s, HWND hWnd,unsigned int wMsg, long lEvent );

参数: s:Socket 对象;

hWnd :接收消息的窗口句柄;

wMsg:传给窗口的消息;

lEvent:被注册的网络事件,也即是应用程序向窗口发送消息的网路事件,该值为下列值FD_READ、FD_WRITE、FD_OOB、FD_ACCEPT、FD_CONNECT、FD_CLOSE的组合,各个值的具体含意为FD_READ:希望在套接字S收到数据时收到消息;FD_WRITE:希望在套接字S上可以发送数据时收到消息;FD_ACCEPT:希望在套接字S上收到连接请求时收到消息;FD_CONNECT:希望在套接字S上连接成功时收到消息;FD_CLOSE:希望在套接字S上连接关闭时收到消息;FD_OOB:希望在套接字S上收到带外数据时收到消息。

具体应用时,wMsg应是在应用程序中定义的消息名称,而消息结构中的lParam则为以上各种网络事件名称。所以,可以在窗口处理自定义消息函数中使用以下结构来响应Socket的不同事件:

switch(lParam)

{

case FD_READ:

break;

case FD_WRITE、

break;

}

(五) 服务器端接受客户端的连接请求

当Client提出连接请求时,Server 端hwnd视窗会收到Winsock Stack送来我们自定义的一个消息,这时,我们可以分析lParam,然后调用相关的函数来处理此事件。为了使服务器端接受客户端的连接请求,就要使用accept() 函数,该函数新建一Socket与客户端的Socket相通,原先监听之Socket继续进入监听状态,等待他人的连接要求。该函数调用成功返回一个新产生的Socket对象,否则返回INVALID_SOCKET。

(六)结束 socket 连接

结束服务器和客户端的通信连接是很简单的,这一过程可以由服务器或客户机的任一端启动,只要调用closesocket()就可以了,而要关闭Server端监听状态的socket,同样也是利用此函数。另外,与程序启动时调用WSAStartup()憨数相对应,程式结束前,需要调用 WSACleanup() 来通知Winsock Stack释放Socket所占用的资源。这两个函数都是调用成功返回0,否则返回SOCKET_ERROR。

3.3 应答模块设计

用户通过浏览器输入网页地址(URL)来访问服务器,而服务器就要求对其发送的请求进行相应的分析,分析客户端的地址,端口,以及请求浏览的文件。所以本人所设计的主干程序为服务器工作线程函数Serverthread,它主要用于接受客户请求的时候,利用多线程来进行处理。其他的函数还有浏览器请求函数,显示信息函数,错误信息函数,及事件处理函数等。最后实现的HTTP服务器具有一般HTTP服务器最基本的功能,可以发布用HTML语言编写的网页,用户可以在已经建立了连接的若干个网页之间切换浏览。

客户端 服务器端

SYN

服务器一直 SYN ACK

ACK

处于监听模式

建立起一个TCP连接

三次握手原理图

3.3.1服务器工作线程函数Serverthread

首先我们介绍服务器工作线程函数Serverthread的基本流程图4.1(见下页)。

图3.1服务器工作线程函数Serverthread流程图

图中很清晰的描述了服务器工作线程函数Serverthread的流程,此设计为简易的WEB服务器所以只对HTML请求的第一行就行分析,对于剩下部分不做分析,还有该HTTP服务器

还不能对CGI请求做出响应,也不能调用相应的ISAPI的DLL(动态连接库)。只能发送最基本的静态文本。

3.4 系统托盘程序

自从微软公司推出Windows 95操作系统以来,系统托盘应用作为一种极具吸引力的用户界面设计深受广大用户的喜爱。使用系统托盘作为用户界面的Windows应用程序数不胜数,比如"金山词霸"、"Winamp"、"RealPlayer"等等。

本次WEB服务器的软件设计为了用户使用方便,使软件界面更随意和简洁,我们也将引入系统托盘程序。

系统托盘程序运行时不显示运行窗口,只在任务栏上显示一个图标,表示程序正在运行,用户可以通过鼠标与应用程序交互,程序开发人员有时也需要编制一些仅在后台运行的类似程序,为了不干扰前台程序的运行界面和不显示不必要的窗口,应使程序运行时的主窗口不可见。同时将一个图标显示在任务栏右端静态通告区中并响应用户的鼠标动作。该程序编译运行后,如果双击托盘图标,程序会弹出一个消息列表窗口,只要鼠标在托盘图标上移动或点击(无论是左右键的单击或双击),产生的消息都会显示在这个窗口里;当鼠标光标移到托盘图标上时,在图标附近会显示提示信息;单击右键时弹出上下文菜单,这个菜单中应包含打开属性页的命令或者打开与图标相关的其它窗口的命令,另外,该程序还可以动态的改变托盘的图标。

3.4.1 系统托盘程序实现方法

为了实现拖盘程序,首先要使程序的主窗口不可见,这点实现起来十分容易,只要调用ShowWindow(SW_HIDE)就可以了,本实例采用的就是这种方法,还有一种思路是通过分别设置主边框窗口的风格和扩展风格来隐藏主框架:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

=WS_POPUP;//使主窗口不可见;

yle =WS_EX_TOOLWINDOW;//不显示任务按钮;

return CFrameWnd::PreCreateWindow(cs);

}

在任务条上显示图标是利用系统API函数Shell_NotifyIcon()来将一个图标显示在任务栏的通告区中。该函数的原型为:

BOOL Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);

该函数的第一个参数dwMessage类型为DWORD,表示要进行的动作,它可以是下面的值之一:

NIM_ADD: 添加一个图标到任务栏。

NIM_MODIFY: 修改状态栏区域的图标。

NIM_DELETE: 删除状态栏区域的图标。

NIM_SETFOCUS: 将焦点返回到任务栏通知区域。当完成用户界面操作时,任务栏图标必须用此消息。例如,如果任务栏图标正显示上下文菜单,但用户按下"ESCAPE"键取消操作,这时就必须用此消息将焦点返回到任务栏通知区域。

NIM_SETVERSION:指示任务栏按照相应的动态库版本工作。

第二个参数pnid是NOTIFYICONDATA结构的地址,其内容视dwMessage的值而定。这个结构在SHELLAPI.H文件中定义如下:

typedef struct _NOTIFYICONDATA {

DWORD cbSize; // 结构大小(sizeof struct),必须设置

HWND hWnd; // 发送通知消息的窗口句柄

UINT uID; // 图标ID ( 由回调函数的WPARAM 指定)

UINT uFlags;

UINT uCallbackMessage; // 消息被发送到此窗口过程

HICON hIcon; // 任务栏图标句柄

CHAR szTip[64]; // 提示文本

} NOTIFYICONDATA;

这样,在WEB服务器源程序里,添加用户自定义消息以及消息函数,托盘程序就实现了。

3.4.2 托盘程序的实际运行

通过上述方法,我们设计所需要的托盘基本功能就能实现了,即在系统选项中设置后台运行项目,在用户单击后,WEB服务器界面将被一个小图标代替,隐藏至Windows右下角的任务栏,在用户需要关掉服务器软件的运行时,则只需要左键单击任务栏服务器图标即可关掉运行中的软件。

实际操作中,在向WEB服务器源程序中添加用户自定义消息、消息函数以及托盘程序后,运行的结果是在用户单击后台运行选项后,服务器运行界面被一个小图标代替,隐藏至Windows右下角的任务栏,但是在鼠标左键单击任务栏服务器图标时候,却无法响应,而导致服务器软件无法正常关闭。

首先,我认识到,实际的托盘程序即服务器运行界面被一个小图标代替,并隐藏至Windows右下角的任务栏的程序并没有错,很有可能是自定义消息或者是自定义函数出了问题,于是,我又开始排查自定义消息以及函数的问题,经过反复验证与检查,并没有发现自定义消息或者是自定义函数出现问题。我又开始寻找响应鼠标单击消息的问题,可是也没有查出问题,最终系统托盘程序还是没有实现鼠标的响应,但我仍然在努力寻找出现的问题与解决方法。

第四章 系统实现

4.1 服务器运行结果

在完成各个模块的构建之后,就基本完成和实现了这个WEB服务器的功能,首先我们运行VC++最后编译出的可执行文件,运行服务器,并开始开启WEB服务器功能,如图4.1所示:

图4.1 开启WEB服务器功能

这样HTTP服务器开始工作了,在左下脚的状态提示框里显示开始侦听连接。

服务器运行之后,我们可以通过各种选项来改变服务器的设置,达到不同要求的需要,如图4.2:

图4.2 服务器选项设置

在普通一栏中可以通过可选项来改变服务器设置,使服务器是否记录访问记录以及在主页面是否显示根目录下的文件夹列表。如图4.3所示:

如图4.3 服务器可变选项

在根目录一栏我们可以自己设置服务器的根目录存放地址与文件夹名称,里面存放的是用户的访问的资源。如图4.4所示:

图4.4服务器根目录选项

在服务器名称这一栏中,我们可以选用默认服务器名称(即服务器运行的计算机名称),也可按照要求或者需要改变服务器的名称,同时,我们也可以设置端口号来改变监听的端口。如图4.5所示:

图4.4服务器名称以及端口号的改变

之后我们在浏览器的地址栏中输入我们所架设的服务器的地址,即531ok(后接的是运行WEB服务器软件的计算机明名),别的联网用户也可以

通过输入正确的地址来请求访问资源。用户发送的请求发送给服务器,服务器就会记录下访问者的地址,时间以及请求的信息,这些信息都会显示在LISTBOX中,具体信息如图4.3所示。

图4.2记录请求信息

服务器会记录下了访问者的信息,在用户输入地址后,后首先见到设计者的主业面,显示了在根目录下可供浏览的文件的名称,大小,上次修改时间以及欢迎信息等,具体信息如图4.4所示:

图4.3主页面具体信息

4.2 编译程序时的问题以及解决方法

1.编译可以通过而不能链接

在编译成功后却出现不能链接的状况,屏幕显示:

LINK : fatal error LNK1104: cannot open file "D:"

Error executing .

最后经过上网查找资料,找到了解决方法:打开VC,Tools--Options--Directories,在show

directories for组合框中选择library files,看看你的lib的路径设置的对不对。如果不到,双击其中的一项,将该路径修改到你的指定目录中即可。这样就解决了上述问题。

2.制作系统托盘程序图标

在vc++编程中,在资源内插入icon,即我们要制作的系统托盘程序图标:

(1)用vc++中的CimageList class 的

BOOL Create(int cx,int cy,BOOL bMask,int nInitial,int nGrow); 初始化。

(2)用Windows的API函数LoadImage()装载图标资源;

(3)用CImageList类的Add(HICON hIcon)函数加将装载后的图表添加到CImageList类对象中去;

(4)调用CToolBarCtrl类的CImageList* SetImageList( CImageList* pImageList )函数将图标列表对象与工具条对象关联起来,从而在工具条上显示出装载的图标。

这样制作者就可以插入自己所需要的ICON,而可以不必使用系统自带的图标。

3.制作自定义消息

在制作自定义消息时必须要在CMainFrame类中添加自定义消息: #define

WM_MY_TRAY_NOTIFICATION WM_USER+0,这样才能使自定义消息有效,之后必须手动添加消息映射,这样才能使你的自定义消息有效,这两点在实际编程中需要多注意,是很容易忽略的两部分。

4.3 程序运行调试结果

在完成服务器软件的编译后,最后的工作就是调式系统和检测软件功能的实现。

首先,编译成功通过后,能正常运行软件,服务器各个选项的设置也能正常修改,并在服务器运行后,各个选项的修改能正确显示出来。

服务器运行后,能正常显示用户的访问记录,在主页面上也能正确显示服务器根目录的所有文件,并提供用户正常浏览和访问。

服务器运行后,可以实现局域网多用户浏览,局域网的用户可以通过输出服务器运行计算机的名称地址,就可访问并浏览服务器内容,由于客观环境因素限制,我只测试了4个用户同时访问成功。

本次设计的WEB服务器基本功能已经实现,但只支持局域网内的用访问和浏览,对于外网的连接请求并不支持,如果需要支持外网用户访问,就需要修改程序中的网络通信部分程序,即SOCKET部分程序,如果时间允许或者以后再有机会接触或实际操作,我会争取做好这部分。

第五章 总结

5.1 设计内容总结

本次设计就是完成一个简易的WEB服务器的设计,实现web服务器基本功能:页面访问请求响应、HTML文件的解析以及数据发送。

本次设计的Web服务器,除了完成网络通信链路的建立和拆除,之外至少还要有二方面的功能:“分折请求” 和“构造响应”。客户端与服务器交换数据之前,首先用TCP/IP建立连接,客户端向服务器请求数据,服务器则向客户端响应并提供数据。客户端和服务器以HTTP协议进行请求和响应。服务器和客户端只能为一次事务处理建立并维持连接,完成一次事务处理后便结束连接。

接收客户端请求、解析客户端请求、响应客户端请求、向客户端回送请求的结果是Web服务器所需完成的主要任务,Web服务器程序代码主要是为了完成这几项任务.

Web服务器通常由以下几个部分组成,也就是本次设计的主要内容:(1)服务器初始化部分.这部分主要完成Web服务器的初始化工作,如建立守护进程、创建TCP套接字、绑定端口、将TCP套接字转换成侦听套接字,进入循环结构,等待接收用户浏览器连接.(2)

接收客户端请求.由于客户端请求以文本行的方式实现,所以服务器一般也以文本行为单位接收.(3)解析客户端请求.这部分工作比较复杂,需要解析出请求的方法、URL目标、可选的查询信息及表单信息.如果请求方法为HEAD,则简单地返回响应首部即可;如果方法是GET,则首先返回响应首部,然后将客户端请求的URL目标文件从服务器磁盘上读出,再发送给客户端;如果是POST,则比较麻烦,首先要调用相应的CGI程序,然后将用户表单信息传给CGI程序,CGI程序根据表单内容完成相应的工作,并将结果数据返回.(4)发送响应信息之后,关闭与客户机的连接.

5.2 设计结论

本次设计的意义在于可以使用户更自由的架设自己的服务器,使自己好的资源让更多的用户共享和浏览,在用户之间构架起最便捷的桥梁,人们就可以使用现有的Web浏览器与该设备进行双向交互、接收或发送信息。它为我们管理、控制和监测各种各样的设备提供了一个很好的途径一基于Internet,也就是说,只要设备接入了Internet,我们就可以在世界上的任何地方十分方便地控制、操纵那些配备有微型Web服务器的设备。

本次设计就是完成一个简易的WEB服务器,实现web服务器基本功能,最后实际设计完成结果基本达到要求,实现了页面访问请求响应、HTML文件的解析以及数据发送。当然,也有很多遗憾,比如系统托盘程序的未能完全实现,以及服务器只能让局域网内的用户访问和浏览,未能实现外网用户的访问功能。这几点是以后如果有机会或者时间一定要争取改进的地方。

参考文献

[1] 李大亮,曲波.嵌入式Web服务器的设计与实现[J].鞍山科技报,2004,27(2)

[2] 罗惟,王萍.一个web服务器的设计[J].现代电子技术,2003,157(14)

[3] 杨阳. 基于URL的Web服务器数据访问[J].网络技术,2003,(10)

[4] 刘波涛,郭麦成. 微型WEB服务器的设计与实现[J].国外电子测量技, 2004, (1)

[5] 贾立华,林碧英. 在超文本协议中实现会话的若干方法[J].现代电力, 2003, (2)

[6] 卢成梁. 简易WEB服务器应答模块设计与研究市场周刊[J]., 2005, (4)

[7] 王茂林 贺富强,Socket 在局域网通信中的应用[J].2006,(5)

[8] 周小松,朱雄军,基于TCP协议的Socket网络编程模式部署及实现,软件技术研究[J],2006(9)

[9] 咏刚,Web开发技术发展史话

[10] 曹衍龙,刘海英,Visual C++ 网络通信编程实用案例精选,2006,(5)

[11] David Pallmann著,Visual C++ 6.0自动、查询和智能代理程序设计,1999


本文标签: 服务器 请求 信息