web服务器设计论文.docx
- 文档编号:11525081
- 上传时间:2023-03-12
- 格式:DOCX
- 页数:24
- 大小:94.27KB
web服务器设计论文.docx
《web服务器设计论文.docx》由会员分享,可在线阅读,更多相关《web服务器设计论文.docx(24页珍藏版)》请在冰豆网上搜索。
……………………………………………………………最新资料推荐…………………………………………………
Web服务器设计——I/O接口的实现
学生姓名:
xx指导老师:
XXX
摘要Web服务器的实现主要是服务器端接受并响应客户端的请求,本次设计是在eclipse开发平台上使用Java编程技术设计Web服务器。
该Web服务器的设计分为两大部分,分别是Web服务器面板的设计与Web服务器I/O接的实现,在本次课程设计中我们首先要建立一个Web服务器的用户面板,使用户能够直观的看到Web服务器的工作,然后实现这个服务器的通信,即实现数据传送。
最后通过对这两个模块的设计及其运行,我们通过在Web浏览器中输入Web服务器的socket,能够实现Web服务器与Web浏览器之间的通信。
关键字AWT组件;Swing组件;Socket套接字;异常处理机制;线程;流
1引言
长期以来,人们只是通过传统的媒体(如电视、报纸、杂志和广播等)获得信息。
但随着计算机网络的发展,人们想要获取信息,已不再满足于传统媒体那种单方面传输和获取的方式,而希望有一种主观的选择性,而由于计算机网络的发展,信息的获取变得非常及时、迅速和便捷。
其中,WWW技术解决了远程信息服务中的文字显示、数据连接以及图像传递的问题,使得WWW成为Internet上最为流行的信息传播方式。
现在,Web服务器成为Internet上最大的计算机群,Web文档之多、链接的网络之广,令人难以想象。
可以说,Web为Internet的普及迈出了开创性的一步,是近年来Internet上取得的最激动人心的成就。
1.1课程设计的目的
通过本次课程设计,加深对计算机网络方面相关的网络知识的理解,熟悉Java语言编程以及eclipse开发平台的运用。
深入理解Web服务器的工作原理,以及如何运用Java语言在eclipse平台上来进行编程设计和实现。
掌握运用Java语言进行面板设计、实现网络连接的方法,在学习理解基本理论知识的同时锻炼独立思考解决问题的能力,并且培养综合运用专业及基础知识,理论联系实际,提高自己动手能力。
1.2课程设计的要求
(1)按要求编写课程设计报告书,能正确阐述设计结果。
(2)通过课程设计培养学生严谨的科学态度,认真的工作作风和团队协作精神。
(3)学会文献检索的基本方法和综合运用文献的能力。
(4)在老师的指导下,要求每个学生独立完成课程设计的全部内容。
1.3设计平台
Eclipse设计平台
本次Web服务器的设计是通过Java语言的程序设计,在Eclipse平台上实现的。
Eclipse是一个开放源代码的、基于Java的可扩展开发平台。
就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。
幸运的是,Eclipse附带了一个标准的插件集,包括Java开发工具(JavaDevelopmentTools,JDT)。
虽然大多数用户很乐于将Eclipse当作JavaIDE来使用,但Eclipse的目标不仅限于此。
Eclipse还包括插件开发环境(Plug-inDevelopmentEnvironment,PDE),这个组件主要针对希望扩展Eclipse的软件开发人员,因为它允许他们构建与Eclipse环境无缝集成的工具。
由于Eclipse中的每样东西都是插件,对于给Eclipse提供插件,以及给用户提供一致和统一的集成开发环境而言,所有工具开发人员都具有同等的发挥场所。
这种平等和一致性并不仅限于Java开发工具。
尽管Eclipse是使用Java语言开发的,但它的用途并不限于Java语言;例如,支持诸如C/C++、COBOL和Eiffel等编程语言的插件已经可用,或预计会推出。
Eclipse框架还可用来作为与软件开发无关的其他应用程序类型的基础,比如内容管理系统。
2设计原理
本次课程设计是要设计一个Web服务器,主要分为两大块,一是图形用户界面的设计,一是I/O接口的实现,即实现Web服务器与客户端(浏览器)之间的通信。
本课程设计只简单说明一下图形界面的设计流程,着重于介绍I/O接口的实现这一块。
在实现I/O接口(服务器与浏览器的通信)中,我们主要运用了Socket套接字、Java线程、Java异常处理机制、输入输出流的设计原理和方法,下面会着重的一一介绍。
2.1图形用户界面设计
AWT组件。
早期的JDK版本中提供了Java抽象窗口工具集(AbstractWindowToolkit,AWT),其目的是为程序员创建图形用户界面提供支持。
AWT组件定义在java.awt包中,包括组件类、组件布局类等。
其中:
组件(component)是构成图形用户界面的基本成分和核心元素。
组件类(Component)是一个抽象类,是AWT组件类层次结构的根类,实际使用的组件都是Component类的子类。
Component类提供对组件操作的通用方法,包括设置组件位置、设置组件大小、设置组件字体、响应鼠标或键盘事件、组件重绘等等。
Swing组件。
Swing组件包含了大部分与AWT对应的组件,而多数的Swing组件相对于AWT组件而言是以“J”开头。
Swing组件与AWT组件的用法基本相同,大多数的AWT组件只要在其类名前加J即可转换成Swing组件。
Swing组件与AWT组件最大的不同是,Swing组件在实现时不包含任何本地代码,因此Swing组件可以不受硬件平台的限制,而具有更多的功能。
由于所有Swing组件均是以AWT的Container类为基础开发的,因此Swing的关键技术还是AWT,Swing库是抽象窗口工具AWT库的扩展,提供了比AWT更多的特性和工具,用于建立更复杂的图形用户界面[1]。
2.2套接字Socket
Socket(套接字)是TCP/IP的编程接口,即利用Socket提供的一组API就可以变成实现TCP/IP协议。
网络上计算机任何一个应用程序都可以通过Socket与其他计算机进行通行。
Socket是通信端点的一种抽象,它提供了一种发送和接收数据的机制[2]。
Socket所要完成的通信就是基于连接的通信,建立连接所需的程序分别运行在客户端和服务器端,其主要步骤为:
(1)建立连接:
首先客户端程序申请连接,而服务器程序监听所有端口,判断是否有客户端程序的服务请求,当客户端程序请求和某个端口连接时,服务器就将Socket连接到该端口上,此时服务器和客户程序之间建立了一个专用的虚拟连接。
(2)数据通信:
客户程序可以像Socket写入请求,服务器程序处理请求并把处理结果通过Socket送回。
(3)拆除连接:
通信结束,将所建立的虚拟连接拆除。
ServerSocket类和Socket类分辨应用于服务器端和客户端的Socket通信,其中,创建了一个ServerSocket对象就创建了一个监听,为了能够随时监听客户端的请求,可以引用ServerSocket对象的accept()方法。
而创建一个Socket对象用于与服务器建立连接,使用指定的端口号使得服务器在捕获到客户端的请求时,根据端口号来完成指定的服务,Socket对象创建成功后,就可以在客户机与服务器之间建立一个连接,并通过这个连接在两个端口之间传送数据。
2.3Java异常处理机制
异常是指应用程序在运行过程中发生的不正常情况,或发生错误。
任何用计算机程序设计语言编写的程序,在运行过程中都不可避免的可能出现各种各样的异常,而程序运行中的异常可以预料但是不可避免,所以我们有必要运用一个异常处理的机制来处理这些有可能出现的异常情况[3]。
异常处理的方式有两种:
第一种方式是使用try……catch……finally结构对异常进行捕获和处理;地二种方式是通过throws和throw抛出异常,本设计中使用的是前者。
try……catch……finally异常处理方式的基本结构为:
try{
}catch(){}
finally{}
其中:
try{}:
将有可能出现异常的代码块括起来,预处理。
程序运行中,如果该块内的代码没有出现任何异常,将正常执行,后面的各catch块不起任何作用;如果该块内的代码出现了异常,系统将终止Try块代码的执行,自动跳转到所发生的异常类对应的catch块中,执行该块代码。
catch(){}:
出现异常,捕捉处理。
一个try块可以对应多个catch块,用于对多个异常进行捕获。
如果要捕获的多个异常之间没有父子关系,各类catch块的顺序无关紧要,但如果他们之间有父子关系,应该将子类的catch放在父类的catch之前,即从小到大排列catch。
finally{}:
无论有没有异常,都会执行,当没有出现异常时,先执行try内代码,再执行finally代码;当出现异常执行完对应异常类的catch块后,再执行finally块。
一般情况用于资源(net,io)的回收。
2.4Java线程
每个java程序都有一个主线程,要实现多线程,必须在主线程中创建新的线程。
Java中,线程用Tread类及其子类的对象来表示。
每个线程都要经历新建、运行、中断和死亡四种状态。
线程的基本实现方法为:
1>构造线程new;2>启动线程Start();3>运行线程run(),因此我们可以得到一个Java线程的建立及运行的基本结构为:
newThread(){
publicvoidrun(){}
}.start()
多线程机制是Java语言的又一重要特征,使用多线程技术可以使系统同时运行多个执行体,这样可以加快程序的响应时间,提高计算机资源的利用率。
实现多线程有两个途径,一种是用Thread类的子类创建来实现,另一种是通过实现Runnable接口的类来实现。
在本设计中是用创建Thread类的子类来实现多线程客户端与服务器端的通信的。
当编写Thread类的子类时,可以在子类中重写父类的run方法,该方法中包含了线程的操作。
这样程序需要建立自己的线程时,值需要建立一个已定义好的Thread子类的实例就可以了。
当创建的线程调用start()方法开始运行时,run()方法将被自动进行[4]。
2.5流
Java的输入/输出是以流的方式来处理的,流是在计算机输入、输出操作中流动的数据序列。
输入流代表从外设流入计算机的数据序列,输出流代表从计算机流向外设的数据序列。
流式输入、输出的特点是数据的获取和发送均按数据序列进行,每一个数据都必须等待排在它前面的数据读入或送出之后才能被读写,每次操作处理的都是序列中剩余的未读写数据中的第一个,而不能随意选择输入输出的位置。
序列中的数据既可以是未经加工的原始二进制数据,也可以是按一定编码处理后符合某种格式规定的特点数据,如字符数据,所以Java中的流有位流(字节流)和字符流之分[5]。
本次课程设计中运用的是字符流,而要实现字符流的传输,其设计顺序为:
获得文件输入输出流;使用转换流将字节流转为字符流;包装;读写;输出流清除缓存;关闭流。
3设计步骤
本次课程设计进行Web服务器的设计与实现,其步骤分为两大步,先要进行用户图形界面的设计与实现,由于它不是本次设计报告的侧重点,故在以下的步骤中只会稍加说明。
而本文的重点在于说明Web服务器I/O端口的实现,即Web服务器是如何实现与客户端(浏览器)的连接与数据传输的,故在下面会详细的说明。
3.1设计流程图
通过分析设计任务,本次课程设计的大致流程如图3.1所示
设计图形界面,并为图形界面添加监听
声明一个图形界面实例变量并调用,引入Frame(图形界面)框架
声明一个ServerSocket
用一个线程Thread和异常处理机制定义start方法
用一个异常处理机制定义stop方法
开始
结束
用一个多线程继承Thread实现服务器端与客户端之间的通信(字符流)
调用主函数main运行
图3.1Web服务器设计流程图
3.2创建用户界面
首先,创建一个顶级的容器组件,一般是继承框架(Frame)的应用程序主窗口,它包含边框、标题栏、控制菜单和内容面板的容器,以下程序段主要是将组件声明并且实例化。
publicclassWebServerFrameextendsJFrameimplementsActionListener
{privateJPanelbtnPan=newJPanel(newFlowLayout(FlowLayout.CENTER));
privateJLabellistenPortLb=newJLabel("Serverlistenport:
");
……
publicWebServerFrame(){
initComponent();//init组件
net=newWebServerNet(this);
}
}
然后,按指定的布局管理器向容器添加组件,给事件的组件添加事件监视器,注册事件处理。
它分为三部分:
对图形用户界面整体进行声明、实例化和布局
privatevoidinitComponent(){}
对控制面板内的组件进行布局和实现其功能
publicvoidbuildBtnPan(){}
对信息面板内的组件进行声明并且实例化,实现其功能
publicvoidbuildHintPan(){}
最后,对按钮的动作进行设置,即设置档用鼠标点击Start和ClearHint按钮时将会出现的状况。
Web服务器用户界面如图3.2所示。
图3.2Web服务器用户界面
3.3I/O接口的实现
本次课程设计报告主要是描述I/O接口的实现,即Web服务器是如何实现与客户端(浏览器)的连接与数据传输的。
在编程时,我们首先第一步是要声明将要用到的实例变量,由于我们需要把设计的两大部分即用户界面部分和I/O接口部分联系起来,故需要声明一个代表用户界面的事例变量frame,并引入WebServerFrame框架。
同时,由于我们要实现通信,故需要声明一个服务器端的ServerSocket对象,创建一个ServerSocket对象就创建了一个监听,用来监听客户端(浏览器)的请求。
其代码段为:
privateWebServerFrameframe;//声明一个frame事例变量
privateServerSocketserverSocket;//声明一个服务器端ServerSocket对象
publicWebServerNet(WebServerFrameframe)//引入Frame框架
{this.frame=frame;}
进行完变量的声明后我们就要开始对相关的方法进行编写了。
首先编写的是start方法,即用鼠标点击“Start”按钮后将会实现的功能。
在编写的start方法中,我们运用了异常处理机制和线程。
其程序段如下所示:
publicvoidstart(Stringport){
try{serverSocket=newServerSocket(Integer.parseInt(port)); frame.addHint(newDate().toLocaleString()+":
Serverstartonport"+port+".");
newThread()//匿名内部类,构造线程
{ publicvoidrun(){//运行线程
try{while(true)//无限循环
{Socketsocket=serverSocket.accept();//随时监听客户端请求
newHandlerThread(socket).start(); }
}
catch(Exceptione)
{JOptionPane.showMessageDialog(frame,e.getMessage());}
}}.start();}//启动线程
catch(Exceptione)
{JOptionPane.showMessageDialog(frame,e.getMessage());}}
从以上的程序段中我们可以看出,实现start方法运用了两个try……catch分别处理可能出现的异常情况,在第一个try……catch异常处理语句中,我们首先创建了一个指定端口的Socket对象来监听该端口,但是端口必须为整型数字,若不为整型,则程序将会出现异常,然后为frame中的“Start”按钮addHint,故点击“Start”按钮将会出现:
当前时间+erverstartonport+IP地址+.。
接下来运用一个匿名内部类来建立一个Thread线程,该线程实现的功能为不断的接收从浏览器客户端发送的请求。
线程的基本实现方法为:
1>构造线程new;2>启动线程Start();3>运行线程run()。
程序中的线程构造方法即为基本实现方法,首先构造了一个线程,即语句中的newThread(){},然后在线程中构造一个执行线程的代码块publicvoidrun(){},线程类里面的业务逻辑都是在run方法中,运行时会自动调用此方法,在构造run()方法中我们运用了一个try……catch异常处理机制,用来处理线程中将会出现的异常,该方法中用while(true)死循环语句和ServerSocket对象的accept()方法来实现不断的接收客户端的请求。
最后调用线程的.start方法来启动线程。
如果以上的方法中的任何一步出现错误,即异常,则由catch语句捕捉异常,即执行catch中的语句。
如此就完成了start方法的实现。
接下来是编写stop方法,它与start方法一样,同样采用了一个异常处理机制,它的try语句为
if(serverSocket!
=null)//ServerSocket不为空
serverSocket.close();//拆除连接
即当ServerSocket不为空(服务器处于正在执行的状态中),强制关闭Web服务器。
在该方法中还采用了一个finally语句,即不管是否出现异常情况,都会执行该语句。
故最后stop实现的功能为:
关闭Web服务器,显示:
当前时间+:
Serverstop.。
接下来是I/O接口实现中最重要的部分,以多线程实现服务器与浏览器之间的数据传送。
该部分使用HandlerThread类继承Thread类的方法,实现多线程的数据流传输。
在这个多线程的实现中,同样的采用了try……catch……finally的异常处理机制来处理能出现的异常情况。
而在多线程的执行块run(){}中,采用了字符流的传输方法。
字符流的传输分为:
获得文件输入输出流;使用转换流将字节流转为字符流;包装;读写;输出流清除缓存;关闭流。
程序中
in=newBufferedReader(newInputStreamReader(socket.getInputStream()));
即完成了文件输入流的获取、字节流向字符流的转换和包装成加强流,
而out=newPrintStream(socket.getOutputStream());
完成了输出流的获得。
接下来是流的读取,即从浏览器提交的请求头部中获得想访问的文件名称,可以用以下代码段来实现。
//从浏览器提交的请求头部中获得想访问的文件名称
Stringsrc=in.readLine().split("")[1];
//将浏览器想获得的文件名称输出至提示框
frame.addHint(newDate().toLocaleString()+":
Client"+hostName+"getfile
"+src+".");
由于程序中是运用的Get方法从服务器上获得数据,而Get是不安全的,因为在传输过程,数据被放在请求的URL中,数据的按照variable=value的形式,添加到action所指向的URL后面,并且两者使用“?
”连接,而“?
”后面的数据即为用户的私人数据,这样就使用户的私人信息变为可见了,这样是极不安全的,故我们采用了一下语句来弥补Get语句带来的安全问题。
/*对浏览器想获得的文件名称进行去除?
后面内容处理*/
//查找字符串,一直到?
为止
intindex=src.indexOf("?
");
//取字符串从0到index,问号后面的就不要了
if(index>=0)
src.substring(0,index);
接下来是输出信息,分为输出响应头部信息和输出响应体部信息。
输出响应头部信息是通过输出流out.println()实现的,之后通过out.flush()语句来清除缓存。
输出体部信息是通过输入流来实现的,其主要语句为:
fin=newBufferedInputStream(newFileInputStream(srcFile));
完成了数据流是传输之后,最后需要关闭流,其代码段为:
//浏览器和服务器间交互的输入流,不为空,关闭流
if(in!
=null)in.close();
//浏览器和服务器间交互的输出流,不为空,关闭流
if(out!
=null)out.close();
//服务器端文件的输入流,不为空,关闭流
if(fin!
=null)fin.close();
以上就完成了Web服务器与客户端(浏览器)之间的数据交换,为了使文件能够被人识别,我们最后还需要对html文件进行解析,其代码段为:
publicStringgetContentType(Filefile)
{ StringfileName=file.getName();
Stringtype=fileName.substring(fileName.indexOf("."));
Stringresult="null";
if(".gif".equals(type))result="image/gif";
elseif(".html".equals(type))result="text/html";
elseif(".htm".equals(type))result="text/html";
elseif(".txt".equals(type))result="text/plain";
elseif(".xml".equals(type))result="text/xml";
returnresult;}
通过这一系列的程序设计后,最终就完成了Web服务器与浏览器之间的通信。
3.4调用主函数运行
调用主函数运行后,将出现Web服务器界面,这时启动Web服务器,然后从另一台连网的计算机上打开一个浏览器,在地址栏里面输入Web服务器的Socket套接字,就可以实现服务器与浏览器的连接,服务器中将出现一系列的信息。
3.5结果分析
编写完所有程序后,在主函数程序中右击鼠标,在出现的菜单栏中单击Run运行,会出现设计的Web服务器界面,界面中出现一行字:
PleaseclicktheSTARTbuttontostartwebserver.。
这时单击“Start”按钮,然后从计算机上打开浏览器,在地址栏里面输入Web服务器的Socket套接字,即输入:
http:
//localhost:
8080,即可实现对本机的连接,服务器面板中显示本
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- web 服务器 设计 论文