web多线程Word文档格式.docx
- 文档编号:16885594
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:14
- 大小:401.40KB
web多线程Word文档格式.docx
《web多线程Word文档格式.docx》由会员分享,可在线阅读,更多相关《web多线程Word文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
这样,它应该总是以一个'
/'
前缀开始,一个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.*;
importjava.util.*;
finalclassHttpRequestimplementsRunnable{
//定义回车换行符
finalstaticStringCRLF="
\r\n"
;
Socketsocket;
//类HttpRequest的构造函数,用于对socket进行初始化.
publicHttpRequest(Socketsocket)throwsException{
添加一行代码,以便初始化socket
this.socket=socket;
//必须实现Runnable接口中的run()方法,实现对HTTP协议Request消息的处理
publicvoidrun(){
try{
//利用方法processRequest实现对Request消息的处理
processRequest();
}catch(Exceptione){
System.out.println(e);
privatevoidprocessRequest()throwsException{
创建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();
在URL标征的文件名前添加"
."
,因为所请求的对象在当前目录下(即该Web服务器的主目录).
fileName="
+fileName;
//打开请求的文件.
FileInputStreamfis=null;
booleanfileExists=true;
fis=newFileInputStream(fileName);
}catch(FileNotFoundExceptione){
fileExists=false;
System.out.println("
到达了一个Request消息!
!
"
);
添加用于调试的信息,以便在控制台输出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){
//如果请求的文件存在
创建Reponse消息的Status行和Content-Type行
statusLine="
HTTP/1.1200OK"
contentTypeLine="
Content-type:
"
+contentType(fileName)+CRLF;
}else{
//如果文件不存在
//todo:
HTTP/1.1404NotFound"
+CRLF;
contentTypeLine="
text/html"
利用HTML创建Web页面,提示用户所请求的文件不存在.Web页面作为Response消息的entitybody部分
entityBody="
<
HTML>
+
HEAD>
TITLE>
不存在<
/TITLE>
/HEAD>
+
BODY>
请求文件不在服务器上<
/BODY>
/HTML>
发送Reponse消息的头部行.
os.writeBytes(statusLine);
os.writeBytes(contentTypeLine);
os.writeBytes(CRLF);
//发送Reponse消息的entitybody部分(响应消息内容).
//调用后面所编写的sendBytes方法,实现文件数据的发送
sendBytes(fis,os);
fis.close();
如果请求的文件不存在,直接发送前面创建的,用于提示用户文件不存在的Web页面
os.writeBytes(entityBody);
关闭所使用的流和Socket.
os.close();
br.close();
socket.close();
privatestaticvoidsendBytes(FileInputStreamfis,OutputStreamos)throwsException{
创建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"
.jpg"
return"
image/jpeg"
.gif"
image/gif"
application/octet-stream"
此外还有textbook,Topology,Topology2,text11等文件
七、测试数据
1.输入服务器的端口号:
8989
2.打开浏览器在地址栏输入:
http:
8989/filename
八、测试情况
1.在地址栏输入http:
8989/yizi.jpg
2、在地址栏输入http:
8989/text.txt
3.在地址栏输入http:
8989/1.jpg
4.在地址栏输入http:
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版)机械工业,(美)卡尔弗特,周恒民译
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- web 多线程