设计说明书模板.docx

上传人:b****6 文档编号:5661198 上传时间:2022-12-30 格式:DOCX 页数:15 大小:403.16KB
下载 相关 举报
设计说明书模板.docx_第1页
第1页 / 共15页
设计说明书模板.docx_第2页
第2页 / 共15页
设计说明书模板.docx_第3页
第3页 / 共15页
设计说明书模板.docx_第4页
第4页 / 共15页
设计说明书模板.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

设计说明书模板.docx

《设计说明书模板.docx》由会员分享,可在线阅读,更多相关《设计说明书模板.docx(15页珍藏版)》请在冰豆网上搜索。

设计说明书模板.docx

设计说明书模板

 

山东建筑大学计算机科学与技术学院

程序设计实用案例选讲大作业说明书

 

题目:

多线程Web服务器的实现

课程:

程序设计实用案例选讲

院(部):

计算机科学与技术

专业:

网络工程

班级:

学生姓名:

学号:

指导教师:

袁卫华

完成日期:

2011/12/1

目录

多线程Web服务器的实现(Java)1

一、问题描述1

二、基本要求1

三、设计思想1

四、系统结构3

五、程序流程(或模块划分)3

六、源程序4

七、测试数据11

八、测试情况11

结论15

参考文献16

课程设计指导教师评语错误!

未定义书签。

多线程Web服务器的实现(Java)

一、问题描述

设计要求:

1.客户端通过浏览器访问Web服务器。

2.Web服务器可以并发地服务多个客户。

3.WebServer可以处理客户端浏览器通过GET+URL方法传来的参数,根据参数生成相应的Web页面,并传递到客户端浏览器。

3.1定义通过URL传递参数的规则(至少包含三种不同的参数);

3.2定义参数格式和处理流程;

3.3根据参数创建Web页面(HTML)。

4.Web服务器必须对出现的问题或错误创建相应的响应消息(WebPage),以对用户进行提示。

二、基本要求

1.熟悉HTTP/HTML规范;

2.熟练运用Eclipse开发环境;

3.掌握Java多线程机制;

4.理解Web服务器工作原理;

5.掌握JavaSocket程序设计;

三、设计思想

服务器和客户机通过http协议进行通信,通过socket服务器时刻监听客户端发送的请求,然后为每个请求创建一个线程。

1.http协议

HTTP(TheHypertextTransferProtocol)是请求---响应协议,客户端发送请求,与服务器建立可靠的tcp连接,服务器通过此连接将响应结果发生给客户端。

一个HTTP请求包含三个部分:

  Method-URI-Protocol/Version-------方法-地址-版本

  Requestheader-------请求头

  Entitybody------请求实体

其中GET是请求的类型,URI完整地指定了Internet资源。

一个URI通常被解析为相对服务器的根目录。

这样,它应该总是以一个'/'前缀开始,一个URL实际上是URI的一种类型。

Version指的是该HTTP请求所用到的HTTP协议版本。

请求头包含了客户端环境与请求实体的一些有用的信息。

例如它包含浏览器设定的语言、实体的长度等等。

每条请求头用回车换行符(CRLF)分开。

  HTTP响应

  与请求相似,HTTP响应也由三部分组成:

  Protocol-Statuscode-Description-------协议状态描述代码

  Responseheaders------响应头

  Entitybody------响应实体

响应头的第一行类似请求头的第一行,显示协议版本是HTTP1.1,请求成功(200=success)不成功(404=notfonunt)。

响应的实体是HTML内容。

头与实体之间由回车换行的空行(CRLF)分开。

2.Socket套接字

在Java应用程序中包提供Socket类和ServerSocket类分别用于客户端和服务器端,在服务器和客户端之间建立连接,实现数据交换。

通过套接字建立连接的过程分为以下3个步骤:

(1)服务器建立ServerSocket对象,负责监听并接收客户端请求。

(2)客户端创建一个Socket对象,向服务器发送请求试图与之建立连接。

(3)服务器接收到客户端请求,为它创建一个单独的进程来处理请求,

创建套接字InputStream和OutputStream流对象,套接字输入、输出流完全可以连接作为一个I/O流对象来对待。

在使用套接字编写客户机/服务器应用程序时,建立客户机和服务器两端相互通信的过程是一样的,该过程的主要工作可归纳为以下4个方面:

打开到套接字的输入、输出流。

根据服务器协议读写数据。

关闭套接字。

3.程序编写:

(1)调用ServerSocket(intport)创建一个服务器端套接字,并前台输入端口号;

(2)监听连接请求,如果客户端有请求连接,调用accept()方法,接受连接,返回通信套接字;

(3)调用Socket类的getOutputStream()和getInputStream()获取输出流和输入流,来响应请求;

(4)最后关闭流和通信套接字。

四、系统结构

整个程序设计结构包括2个java类

(1)WebServer11类实现监听并接受请求

(2)和HttpRequest11处理请求并处理,产生响应的结果

五、程序流程(或模块划分)

根据HTTP协议的作用原理,Socket编程,Web服务器的工作原理,实现GET请求的Web服务器程序的流程如下:

(1)创建ServerSocket类对象,监听端口9090。

这是为了区别于HTTP的标准TCP/IP端口80而取的特定端口;

(2)等待、接受客户机连接到端口9090,得到与客户机连接的socket;

(3)创建一个HttpRequest对象,将标征着所建立TCP连接的Socket作为参数传递到它的构造函数中

(4)为了让HttpRequest对象在一个单独的线程中处理随后的HTTP请求,我们首先创建一个Thread对象,将HttpRequest对象作为参数传递给Thread的构造函数,然后调用Thread的start()方法启动线程

(5)HttpRequest必须实现Runnable接口。

因此,必须定义HttpRequest的public方法run(),实现多线程

(6)利用类StringTokenizer从Request行中解析出文件名字。

(7)从请求信息中获得参数的值,使用ProcessRequest处理请求方法进行参数处理

(8)经过处理请求信息将得到一个html的文件名,如果该文件存在,则打开文件,把HTTP头信息和文件内容通过socket传回给Web浏览器,然后关闭文件。

否则向服务器发送错误信息;

(9)关联的输入流和输出流,关闭socket

六、源程序

MultiThreadWebServer.java:

创建服务器套接字,侦听客户端请求,为每个请求创建一个线程

/**************************************************************

*MultiThreadedWebServer的启动采用如下形式:

*

*javaMultiThreadedWebServerport_number*

*port_number为一整数,(1024<=port_number<=65535)*

*在客户端浏览器地址栏中输入如下形式地址访问服务器:

*

*http:

//localhost:

port_number/textbook.jpg*

***************************************************************/

import.*;

publicfinalclassMultiThreadedWebServer{

publicstaticvoidmain(Stringargv[])throwsException{

//从命令行中获得WebServer的监听端口号

//intport=(newInteger(argv[0])).intValue();

//todo:

添加代码以创建监听Socket

ServerSocketsocket=newServerSocket(8989);

while(true){

//ListenforaTCPconnectionrequest.

Socketconnection=socket.accept();

//创建对象,处理收到的HttpRequest消息

HttpRequestrequest=newHttpRequest(connection);

//创建线程,不同的消息用不同的线程进行处理

Threadthread=newThread(request);

//启动线程.

thread.start();

}

}

}

HttpRequest.java实现了Runnable接口,对请求进行处理并做出响应

/*

1.通过实现Runnable接口实现多线程

2.网络相关处理机制包含在包中

3.HttpRequest类中使用的某些对象包含在java.util包中

4.将收到的HTTPrequest消息作为参数来创建HttpRequest类的实例

5.线程一启动将处理完该Request消息

*/

/*需要添加代码的地方用//todo:

标注*/

importjava.io.*;

import.*;

importjava.util.*;

finalclassHttpRequestimplementsRunnable{

//定义回车换行符

finalstaticStringCRLF="\r\n";

Socketsocket;

//类HttpRequest的构造函数,用于对socket进行初始化.

publicHttpRequest(Socketsocket)throwsException{

//todo:

添加一行代码,以便初始化socket

this.socket=socket;

}

//必须实现Runnable接口中的run()方法,实现对HTTP协议Request消息的处理

publicvoidrun(){

try{

//利用方法processRequest实现对Request消息的处理

processRequest();

}catch(Exceptione){

System.out.println(e);

}

}

privatevoidprocessRequest()throwsException{

//todo:

创建socket所关联的输入流is和输出流os

InputStreamReaderis=newInputStreamReader(socket.getInputStream());

DataOutputStreamos=newDataOutputStream(socket.getOutputStream());

BufferedReaderbr=newBufferedReader(is);

//todo:

添加一行代码,获取所收到HTTPRequest消息的RequestLine

StringrequestLine;

requestLine=br.readLine();

System.out.println();

System.out.println(requestLine);

 

//Request消息的Requestline中包含:

MethodURLVersion三个字段.利用StringTokenizer类简化读取字段的操作

StringTokenizertokens=newStringTokenizer(requestLine);

//跳过Method字段,因为它应该是GET

tokens.nextToken();

//获取头部行中的URL字段值

StringfileName=tokens.nextToken();

//todo:

在URL标征的文件名前添加".",因为所请求的对象在当前目录下(即该Web服务器的主目录).

fileName="."+fileName;

//打开请求的文件.

FileInputStreamfis=null;

booleanfileExists=true;

try{

fis=newFileInputStream(fileName);

}catch(FileNotFoundExceptione){

fileExists=false;

}

System.out.println("到达了一个Request消息!

!

!

");

//todo:

添加用于调试的信息,以便在控制台输出HTTPRequest消息全部headerline的内容

StringheaderLine=null;

while((headerLine=br.readLine()).length()!

=0){

System.out.println(headerLine);

}

 

//创建Reponse消息.

StringstatusLine=null;//状态行

StringcontentTypeLine=null;//Content-Type行

StringentityBody=null;//Entitybody部分

if(fileExists){

//如果请求的文件存在

//todo:

创建Reponse消息的Status行和Content-Type行

statusLine="HTTP/1.1200OK";

contentTypeLine="Content-type:

"+contentType(fileName)+CRLF;

 

}else{

//如果文件不存在

//todo:

创建Reponse消息的Status行和Content-Type行

statusLine="HTTP/1.1404NotFound"+CRLF;

contentTypeLine="text/html";

 

//todo:

利用HTML创建Web页面,提示用户所请求的文件不存在.Web页面作为Response消息的entitybody部分

entityBody=""+

"不存在"+

"请求文件不在服务器上";

 

}

//todo:

发送Reponse消息的头部行.

os.writeBytes(statusLine);

os.writeBytes(contentTypeLine);

os.writeBytes(CRLF);

 

//发送Reponse消息的entitybody部分(响应消息内容).

if(fileExists){

//调用后面所编写的sendBytes方法,实现文件数据的发送

sendBytes(fis,os);

fis.close();

}else{

//todo:

如果请求的文件不存在,直接发送前面创建的,用于提示用户文件不存在的Web页面

os.writeBytes(entityBody);

}

//todo:

关闭所使用的流和Socket.

os.close();

br.close();

socket.close();

 

}

privatestaticvoidsendBytes(FileInputStreamfis,OutputStreamos)throwsException{

//todo:

创建buffer,将请求的文件数据读入buffer,然后通过输出流os发送到客户端

byte[]buffer=newbyte[1024];

intbytes=0;

while((bytes=fis.read(buffer))!

=-1){

os.write(buffer,0,bytes);

}

 

}

//contentType方法用于根据文件的扩展名,确定Content-Type头部行

privatestaticStringcontentType(StringfileName){

//todo:

根据文件的扩展名,返回填写在conten-type中的内容

if(fileName.endsWith(".htm")||fileName.endsWith(".html")){

return"text/html";

}

if(fileName.endsWith(".jpg")){

return"image/jpeg";

}

if(fileName.endsWith(".gif")){

return"image/gif";

}

return"application/octet-stream";

 

}

}

此外还有textbook,Topology,Topology2,text11等文件

七、测试数据

1.输入服务器的端口号:

8989

2.打开浏览器在地址栏输入:

http:

//localhost:

8989/filename

八、测试情况

1.在地址栏输入http:

//localhost:

8989/yizi.jpg

 

 

2、在地址栏输入http:

//localhost:

8989/text.txt

 

 

3.在地址栏输入http:

//localhost:

8989/1.jpg

 

4.在地址栏输入http:

//localhost:

8989/haokan.jpg

结论

设计中遇到的问题如何实现服务器的多线程,如何使客户端和服务器实现通信,及响应结果如何发送给客户端。

1.Web服务器将是多线程的,所收到的每个Request消息将交由单独的线程进行处理。

这使得服务器可以并发地为多个客户服务,或者是并发地服务于一个客户的多个请求.当创建一个新线程时,需要向线程的构造函数传递实现了Runnable接口的类的一个实例(即通过实现接口Runnable来实现多线程)。

这正是我们定义单独的类HttpRequest的原因。

创建监听端口以等待TCP连接请求。

由于Web服务器将不间断地提供服务,我们将侦听操作放在一个无穷循环的循环体中。

这意味着需要通过在键盘上输入^C来结束Web服务器的运行。

2.为了将类HttpRequest的实例作为参数传输传递到Thread的构造函数中,HttpRequest必须实现Runnable接口。

因此,必须定义HttpRequest的public方法run(),其返回值类型为void。

我们在run()中调用实现Request消息处理绝大部分操作的方法processRequest()。

3.由于之前对HTTP的协议格式不熟悉,在发送HTTP响应消息实体时出现问题:

显示页面与发送的页面有出入,请教了马老师后,发现了自己的错误:

每个头信息都是一行,“Content-Length”头信息是必需的,它表示要读取多长的实体,而且头信息和实体之间有一个空行,这些都正确后才能看到想要的页面效果。

4.运行时发现无法显示请求存在的文件,经过请教指导老师,调试发现使输入输出量方面使用错误,还有相关的方法不知具体如何应用。

经过课程设计发现自己的知识掌握的还不牢固,应用能力需要加强。

Java编程要经常复习和练习。

在计算机网络方面,两台机器如何实现通信,socket及http具体的功能和作用,

 

参考文献

1、RFC2616-HypertextTransferProtocol--HTTP/1.1

2、RFC1866-HypertextMarkupLanguage-2.0

3、RFC2854-The'text/html'MediaType

4、《Java实例入门》刘勇,中国青年出版社,2002-01-01

5、《Java程序设计与案例》刘宝林;高等教育出版社

6、JavaTCP/IPSocket编程(原书第2版)机械工业,(美)卡尔弗特,周恒民译

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1