




已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
. . . . .基于Java的高效兼容HTTP服务器的研究及实现目录摘要 1一、引言 4二、HTTP 服务器模型 5(一)超文本传输协议5(二)Java API中网络类包简介6(三)HTTP客户机与服务器的交互涉及骤 7(四)HHTP操作的一次事务(Transaction) 8 (五)HTTP消息8三HTTP服务器的兼容性9四Java实现多线程HTTP服务器设计 10(一)Java语言网络编程 10(二)服务器总体设计 121总体设计的关键点 122模块设计123HTTP服务器各类之间关系 14(三)服务器详细设计分析151线程重用152各类和接口的主要功能15(四)Java多线程机制的应用17五HTTP服务器运行23六结束语 24参考文献25一引言SUN推出Java语言之后,全世界的目光都被这个神奇的语言所吸引,Java语言从一开始就内置了支持网络编程,因此更容易编写网络应用程序;这也是与其他编程语言不同的地方。Java提供了大量类和接口可以处理各种网络协议,共享信息,并行计算,应用程序服务等优秀特点使java技术将会得到广泛的应用。Java是实现定制客户机和服务器的优秀工具,因为它支持多种在网络上发送和接收数据提供服务接收数据调用服务的技术。Java作为一种面向分布式计算机环境语言,提供了完全意义的多线程支持,利用多线程编程接口,可以方便地写出支持多线程的应用程序,这一点也是Java所特有的。随着Internet的普及和Web技术的迅速发展,客户/服务器结构逐渐转向浏览器/服务器方向,Web文本发布具有简洁生动形象等特点,适用于发布信息,开发基于Browser/Server模式的Web数据库信息检索系统得到广泛应用。Web服务基于超文本传输协议(HTTP协议)。Java语言所具有的良好兼容性安全性健壮性及可扩展的跨平台等特性,使得Java成为开发基于B/S模式的Web数据库应用的首选计算机语言。本文使用Java开发一个高效兼容的HTTP服务器原型。(如图一)。 图一 HTTP服务器原型 该多线程HTTP服务器使用ServerSocket(服务器套接字)运行在服务器专用的TCP端口监听接收来自客户端的请求。当远程主机上的客户Socket试图与指定端口建立连接时,服务器被激活,根据具体情况来确定重用旧线程或生成一个新线程来响应客户端的请求直到该客户退出。服务器的主线程仍然处于监听状态,等待新客户请求。二HTTP 服务器模型(一)超文本传输协议(HTTP,Hypertext Transfer Protocol)是Web浏览器与Web服务器之间通信的标准协议,是个相当详细的协议。位于TCP/IP协议的应用层,具有简单通用无状态灵活无连接及面向对象等特点是互联网中最核心的协议之一。HTTP是RPC式的协议。RPC就是远程调用(Remote Procedure Call),是请求远程机服务和处理机制。RPC和编程语言中的过程调用相似,基于C/S和B/S模型,它建立在请求/响应(Request/Response)的基础上,服务端和客户端可能位于不同的独立系统上,客户端通过TCP SOKET向服务器端口(默认为80)发送包含请求方法URL(是对统一资源定位符(Uniform Resource Locator)用来标识Internet上资源的位置。URL类是不能再小的最小类,它扩展Java.lang.Object。)和协议版本信息,请求建立Socket连接,客户的请求通过Socket被服务器接收,服务器对客户的请求信息参数进行分析处理,响应一个状态行,对客户的请求服务做出回应,把相应的资源文档以流形式通过Socket传给客户浏览器,整个过程见(图二)所示: 图二 Socket 连接(二)Java API中网络类包简介: Java API中按类的形式提供了三种不同层次的网络技术机制,用URL(统一资源定位符)访问网络资源的类,利用Socket(套接字)通讯的类以及DataGran(数据报)类。前两种类方法更能体现Java作为网络语言的特点,支持URL类实际上也是依赖于下层支持Socket类方法来实现的。相对来讲,URL是对WEB的高层联接。Socket是一种底层的连接,客户机和服务器通过写入到Socket的字节流进行通信。Java系统的网络通信机制如图二所示,本文主要讨论基于Socket类的通信机制。InternetJAVA的网络通信机制支持URL的类支持SOCKET的类图三 JAVA系统的网络通信机制应用程序1应用程序1网间网编程界面TCP/IP核心协议物理介质图四 应用程序和TCP/IP核心协议关系协议组TCP/IP的组合, TCP/IP技术的核心部分是传输层(TCP和UDP协议),网络层(IP)协议和物理层(面向各种物理硬件技术),能实现这三层协议的内核可称之为TCP/IP网络操作系统.TCP/IP协议技术中的中下层协议向外提供的只是原始的编程界面,而不是直接的用户服务,用户服务要靠核外的应用程序实现.应用程序和TCP/IP核心协议关系如图四所示.(三)HTTP客户机与服务器之间的交互涉及下列步骤:1HTTP服务器听取请求:HTTP服务器打开听取端口,通常是端口80,这是在一个线程中进行的,然后线程阻止,等待入站的HTTP请求。2HTTP客户机构造HTTP URL:HTTP客户机需要建立与HTTP服务器的初始连接。为此要使用URL,通常情况下是以http:/www.any_的形式。这里HTTP客户机指定HTTP服务器上的缺省资源,通常是页面index.htm或default.htm 。缺省Web页面通常是站点的主页。有时候URL会更加复杂。3HTTP客户机建立连接:HTTP客户机建立发送套接,连接Web服务器。发送套接让客户机向服务器提交HTTP请求。4HTTP服务器接受连接:HTTP服务器生成接受套接,从HTTP客户机接受请求。通常,接受套接在另一线程中运行,提高Web服务器的性能。5HTTP客户机构造一个HTTP请求,发送到HTTP服务器:建立与HTTP服务器的连接之后,客户机构造HTTP请求并通过套接将其传递到HTTP服务器。6HTTP服务器处理请求:HTTP服务器继续听取接受套接中的入站请求。得到请求时,服务器分析入站请求,并采取请求要求的操作。7HTTP服务器将HTTP响应发送给HTTP客户机:HTTP服务器构造HTTP响应,有六个部分(1)、HTTP版本;(2)、HTTP状态码;(3)、HTTP状态描述(可选);(4)、响应头字段(可选);(5)、响应体(可选);(6)、内容长度(可选)。服务器通过与HTTP客户机的连接返回响应。8HTTP客户机处理响应:HTTP客户机收到服务器的响应时,客户机分析响应,然后处理响应。9关闭套接连接:HTTP客户机或服务器关闭连接。(四)一次HHTP操作称为一次事务(Transaction)。HTTP定义的事务处理由以下四步组成:1 客户与Web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接成功。2 客户通过socket向Web服务器提交请求。一般为GET或POST命令。3 通过HTTP协议传送给Web服务器。接纳则进行事务处理,处理结果传回客户端。4 客户和服务器断开连接。HTTP采用TCP连接,该连接仅在此事务中保持,浏览器和服务器都不会记忆上次的连接状态。HTTP之所以采取这种无状态机制,完全是为了提高服务器的工作效率。在WEB中点击一个超链接时,浏览器有可能从当前站点转到另一个站点。因此,当文档传输完毕时,服务器都假定用户要退出对文本服务器上的文档的浏览连接,因而断开连接。如果继续浏览,就再次建立连接。如果用户确实要退出时,服务器就不需要执行任何操作,因为连接已经断开了。(五) HTTP消息包括HTTP请求信息和HTTP响应消息两种,一个HTTP请求格式如下图五所示: 图五 HTTP请求信息格式 HTTP响应信息格式如图六所示: 图六 HTTP响应信息格式三HTTP服务器的兼容性(一) HTTP1.1的兼容性:要实现一个实用高效的HTTP1.1和CGI兼容HTTP服务器, HTTP1.1主要通过引入持久连接和更好的缓存验证命令而提高性能,而且把HTTP响应代码增加一倍多。能够向上兼容HTTP/1.0,HTTP消息包括请求消息和响应信息两种。(二) HTTP1.0的兼容性:HTTP1.0兼容服务器总是要响应请求的HTTP版本,可能是HTTP0.9或HTTP1.0。HTTPResquest要检查请求中是否存在版本号。如果不存在,则假设为HTTP0.9。这个版本不用头。其中在HTTP1.0版本里请求头的method可能为GETPOST或HEAD,而在HTTP1.1版本中增加了PUT和DELETE两种请求。URL统一资源定位器标明了目的位置。(三) 与旧版本HTTP的兼容性:HTTP1.0规范强制要求与HTTP.09的向下兼容性。我们要保证HTTP服务器具有下列功能:1识别HTTP0.9与HTTP1.0请求的请求行格式。2了解HTTP0.9与HTTP1.0格式的任何有效请求。3响应与客户机使用的相同协议版本消息。四Java实现多线程HTTP服务器设计(一)Java语言网络编程在java的客户/服务器应用中,客户与服务器之间的通讯一般是采用基于TCP/IP的Socket机制来实现的。当通信数据到达的是目的主机网络层,IP地址连同端口号一起,提供了对两台机器之间唯一的无二义性的连接的标识,这个连接叫套接字(Socket)。一对套接字为一标识了每个端口连接:(1)发送方套接字=源IP地址+源端口号;(2)接收方套接字=目的IP地址+目的端口号。Socket类实现基于连接客户插口。我们可以利用Java API中的J 包中的插口类提供的套接字功能进行网络编程。Socket类(套接字类)提供的重要函数有getInetAddress( ), getPort( ), getInputStream( ), 和close( )。分别产生用于获得信宿机的地址、信宿机端口号、获得输入流、获得输出流、关闭套接字。ServerSocket类(服务器套接字类)的重要函数有:getInetAddress( ), getLocalPort( ), accept( )和close( ),分别用于获得信宿机的Internet地址、本地端口、监听和关闭套接字。ServerSocket类实现了TCP服务器插口。它提供两种构造函数指定服务器插口所用的端口,以便监听到连接请求。利用Accept( )方法引发服务器插口监听并等待,一旦连接就返回一个实例。自定义类包括(1)HttpServer类(服务器类),(2)ReThead(线程重用类),(3)HttpProcess(一个接口类)。此外还包括各个类的请求处理类3个:HttpFile(静态文件处理), HttpCGI(CGI处理) ,HttpException(出错处理);以及数据流处理2个:HttpInputstream(数据输入流)和HttpOutputstream(数据输出流)。HTTPRequestHttp服务器初始化HTTPConfig初始化HTTPLog初始化HTTPConverter当浏览器连接时建立浏览器连接分析器建立连接信息HTTPMessageHeadersHTTPInfo发回响应和对象HTTPGetHandHTTPHeadHTTPHandler建立HTTPResponse生成请求的对象HTTPFileObjectHTTPProcessObject建立相应处理器图七 重要类的交互(二)服务器总体设计1总体设计的关键点根据HTTP工作原理,在这个设计中抓住了几个关键点:(1)持续监听。根据TCP/IP,作为服务器端进行监听。在这个设计中,采用了一个永真的循环,等待客户的连接请求。(2)可以同时接受多个用户的连接请求。每个用户拥有自己独立的线程。(3)实现了线程的重用性。线程重用服务可以自动收集可重用的线程,以免过的的创建与销毁线程增加系统的负担,提高了系统的效率。2模块设计把Http服务器分成两个组成模块:客户请求处理模块和响应生成发送模块,其中客户请求处理模块负责接收客户的连接,分析请求中的各个协议参数,此外还负责调用响应生成发送模块。而响应生成发送模块的任务就是根据对客户请求的分析的结果查找资源,生成响应和发送响应。(1)客户请求处理模块的任务就是负责监听系统的端口,以获取客户机到达本机的连接。当获得一个连接请求时,就把这一连接所建立的套接字连接交给一个负责客户请求处理程序Client类处理这一个客户的请求,之后程序继续监听等待下一个客户的连接。在一个Client对象建立之后,它就把其在初始化时获得的一个Socket对象的输入流重定向给一个Request对象,使其能通过Request类提供的接口方法获取这一用户请求的相关参数,如URL的组成请求方法,所指文件以及协议版本等数据。然后把这一个Request对象连同Socket对象的输出流传递给一个ResourceHandler类的实例,由这一个ResourceHandler对象完成生产发送对用户请求的响应。主要由三个部分组成:守护程序:一个HttpServer类的实例对象;客户处理程序:一个Client用户类,由HttpServer对象负责建立其实例和执行其运行线程;请求分析程序:一个Request用户类,由Client对象初始化其对象实例,用于分析客户请求中的协议参数(如下图八)。其中,1调用;2Socket对象;3Socket对象;4Socket对象输入流;5Request对象;6Socket对象的输入流和Request对象。Request对象是指经分析的客户请求。 654321总控程序守护程序客户处理程序请求分析程序 响应生成模块 图八 请求处理模块 (2)响应生成发送模块实现的功能就是从客户请求程序中接受一个Request对象和一个标识一个用户连接的客户Socket对象的输入流(HttpInputStream)对象。通过Request对象中获得客户请求的协议参数,查找客户请求指定的资源,根据查找的结果,生成相应的响应,并把生成的响应写入到指定的HttpInputStream对象中,其操作结果就是把响应送往客户。包含了以下对象:ResourceHandler对象(响应产生发送处理)、SCManager(响应的状态码管理)对象、StatusCode对象(状态码管理)、MimeType对象(媒体类型描述处理),通过相互调用协调,共同完成模块的功能(如图六)。其中:1Socket对象的输入流和Request对象;2文件名;3文件描述;4状态码;5状态码相关描述;6文件名;7媒体类型描述。654321响应生成发送程序状态码管理程序媒体类型识别程序文件系统7 图九 响应生成发送模块3HTTP服务器各类之间关系 在Http服务器的设计中,Httpserver是主类,提供了程序的入口,打开ServerSocket类,并且接受客户端的连接。对于每个连接将创建一个新的Httpserver对象去处理客户端的请求,并且启动一个新的线程去执行该处理。HttpInputstream类对于请求信息进行分析。HttpProcessor类则提供了真正处理的接口,它分别被HttpFile类,HttpCGI类,HttpException类来实现。最后将响应信息由HttpOutputStream类格式化输出到客户端。HTTP服务器类图设计如(图十)所示:对请求进行分析处理客户端响应请求browserHttpserverMain( ) ReThreadRun( )HttpOutputStreamHttpInputStreamHttpProcessorProcessorRequest( )HttpFileHttpCGIHttpException 图十 HTTP服务器类图(三)服务器详细设计分析线程重用在这个设计中用Rethread类来划分线程,这个类用一个矢量(Vector)来存储线程。这样避免了旧线程的销毁,并且当客户端有请求过来时,避免了新线程的创建,提高了服务器的响应效率。各类和接口的主要功能()HTTPServerHTTPServer.java中定义了一个变量类resources,保存这个类的所有场景特定消息。把这个变量定义为静态的,因为他在静态main()方法中使用。()HTTPRequestHTTPReques类处理HTTP请求。对于每个接受的连接,HTTPServer run()方法构造一个HTTPRequest对象并传入从accept()调用取得的套接参数,作为服务器与浏览器进行通信的端点。构造HTTPRequest对象之后,run()方法调用start(),使请求在并发运行的线程中处理。这样HTTPServer类的run()方法可以立即继续,等待新的入站连接。()HTTPInPutStream对于每个请求信息,用HTTPInPutStream类来进行分析处理,包括解释请求和读取所有请求报头。把这个类中请求进行分解为方法请求路径查询字符串以及协议版本,并且读取所有随后的请求报头。()HTTPOutPutStream经过处理后的响应信息经过HTTPOutPutStream类进行格式化输入到客户端,这个类为写HTTP响应提供了支持,在这个类中添加了形成和发送HTTP响应报头的支持,包括状态行和随后的报头。()HTTPProcessorHTTPProcessor接口提供了真正处理的方法,HTTPFile类,HTTPCGI类,HTTPException类分别实现了该接口。根据HTTPInPutStream类的分析来确定所有请求的信息该有哪个类来处理。(HTTPFile类HTTPCGI类或HTTPException类)()HTTPFile该类实现了HTTPProcessor接口,用于处理静态文件资源的get和head请求。()HTTPCGI该类实现了HTTPProcessor接口,用于处理CGI程序。()HTTPException该类是IOException的子类,它用于把HTTP错误返回到客户机。它实现HTTPProcessor接口,因此当在响应客户机请求而被抛出时,他能够发送一个适当的HTTP错误信息到客户机。(四)Java多线程机制的应用 多线程(Multi-Thread)是Java的一个重要特性,指的是通过系统的调度使几个具有不同功能的程序流即线程同时并行的运行。 Java从语言一级提供对线程的支持,可由语言和运行系统联合提供对共享数据段的管理功能和同步机制,这样就使多线程并行程序设计相对比较容易。 在Java中,当我们创建一个新线程时,先通过对Java.lang.Thread类的继承来派生一个子类class MyApplication extends Thread 然后,通过run( )方法实现线程的行为。class MyApplication extends Thread public void run( ) 最后,由子类生成一个对象,并且进行启动操作,这样就得到一个处于可运行状态的线程。生成对象是完成线程的创建,启动则是对已经创建的线程进行操作。 My Application ex=new My Application( ); Thread th=new Thread(ex); Th.start( );这个服务器端程序以最简单的方式运用Socket对服务器和客户机进行操作。服务器的全部工作就是等候建立一个连接,然后用那个连接产生的Socket创建一个InputStream以及一个OutputStream。在这之后,它从InputStream读入的所有东西都会反馈给OutputStream,直到接收到行中止(END)为止,最后关闭连接。public class myServer / 这个是服务器端程序/ 设定服务程序端口号,大于1024public static final int PORT = 8080;public static void main(String args) throws IOExceptionServerSocket s = new ServerSocket(PORT);System.out.println(Started:+s);try Socket socket = s.accept(); try System.out.println(连接被接受+socket); BufferedReader in =New BufferedReader(new InputStreamReader(socket.getInputStream(); PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream(),true); while(true) String str = in.readLine(); if(str.endsWith(END) break; System.out.println(Echoing: +str); out.println(str); catch(Exception e) System.out.println(e.toString(); finally System.out.println(closing .); socket.close(); finally s.close(); 图十一 多线程服务端实例下面是该服务器设计的部分代码:* get Connect Info */ public String getConnectInfo() String szClientHostName=this.m_sClient .getInetAddress().getHostName (); String szClientAddress=this.m_sClient .getInetAddress ().getHostAddress(); int ClientPort=this.m_sClient .getPort (); String szRet=; szRet=Accepted connection from +szClientHostName+(+szClientAddress+) +on port +ClientPort+.; return szRet; HTTPRequest(Socket client)throws IOException this.m_sClient =client; this.m_In =new HttpInputStream(this.m_sClient.getInputStream(); this.getRequest (); public String getLog() StringBuffer szRet=new StringBuffer() ; szRet.append (Received the following request:+n); Enumeration enum=m_vLines.elements (); String szstr1=; while(enum.hasMoreElements() szstr1=(String)enum.nextElement(); szRet.append (szstr1+n); return szstr1.toString(); boolean isGetRequest() if(this.m_vLines .size ()0) String firstline=(String)this.m_vLines.elementAt (0); if(firstline.length ()0) if(firstline.substring(0,3).equalsIgnoreCase (GET) return true; return false; * only use to recognize methed get */class HttpInputStream extends FilterInputStream HttpInputStream(InputStream in) super(in); public void addLine(String line) m_vLines .addElement(line); public String readLine() throws IOException StringBuffer result=new StringBuffer (); boolean finished=false; boolean isenter=falsePublic static void main (String args) throws IOException ServerSocket server = new ServerSocket (8080);/*创建一个监听8080端口的服务器套接字*/While(time) Socket client = server.accept ( );/*等待一个连接,如果该连接未被创建,本方法阻塞当前线程。返回值是一个Socket对象,服务器程序利用这个对象与连接的客户通信。*/HttpServer HttpServer =new HttpServer(client);/*创建一个HttpServer 类的对象*/ ReThread ReThread = new ReThread (Httpserver);/*创建新线程*/ Rethread.s
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学校教育与职业技能培训协议
- 企业运营成本控制方案库
- 艺术流派及发展历程概述:美术课堂教学设计
- 直接引语与间接引语的转换规则:六年级英语语法课教案
- 小猪学样550字(11篇)
- 纪念塔课件教学
- 银滩之旅250字(12篇)
- 关于七夕节的英语作文11篇
- 2025年事业单位招聘统计类试卷:统计学在美学中的
- 2025年商务英语(BEC)中级考试真题模拟卷:模拟实战演练
- 园林绿化工高级技师知识考试题库(附含答案)
- 安医大生殖医学课件04胚胎的培养
- 可下载打印的公司章程
- 关于推荐评审高级工程师专业技术职务的推荐意见报告
- 少先队辅导员工作记录表(共7页)
- Q∕GDW 10356-2020 三相智能电能表型式规范
- 教研工作手册
- CINV化疗相关呕吐课件
- 应届毕业生培养计划方案
- 独树一帜的中国画(课堂PPT)
- 生产设备控制程序
评论
0/150
提交评论