java实现web服务器.docx

上传人:b****8 文档编号:9403320 上传时间:2023-05-18 格式:DOCX 页数:30 大小:26.28KB
下载 相关 举报
java实现web服务器.docx_第1页
第1页 / 共30页
java实现web服务器.docx_第2页
第2页 / 共30页
java实现web服务器.docx_第3页
第3页 / 共30页
java实现web服务器.docx_第4页
第4页 / 共30页
java实现web服务器.docx_第5页
第5页 / 共30页
java实现web服务器.docx_第6页
第6页 / 共30页
java实现web服务器.docx_第7页
第7页 / 共30页
java实现web服务器.docx_第8页
第8页 / 共30页
java实现web服务器.docx_第9页
第9页 / 共30页
java实现web服务器.docx_第10页
第10页 / 共30页
java实现web服务器.docx_第11页
第11页 / 共30页
java实现web服务器.docx_第12页
第12页 / 共30页
java实现web服务器.docx_第13页
第13页 / 共30页
java实现web服务器.docx_第14页
第14页 / 共30页
java实现web服务器.docx_第15页
第15页 / 共30页
java实现web服务器.docx_第16页
第16页 / 共30页
java实现web服务器.docx_第17页
第17页 / 共30页
java实现web服务器.docx_第18页
第18页 / 共30页
java实现web服务器.docx_第19页
第19页 / 共30页
java实现web服务器.docx_第20页
第20页 / 共30页
亲,该文档总共30页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

java实现web服务器.docx

《java实现web服务器.docx》由会员分享,可在线阅读,更多相关《java实现web服务器.docx(30页珍藏版)》请在冰点文库上搜索。

java实现web服务器.docx

java实现web服务器

一个Web服务器也被称为HTTP服务器,它通过HTTP协议与客户端通信。

这个客户端通常指的是Web浏览器。

一个基于Java的Web服务器用到二个重要的类,.Socket与.ServerSocket,并通过HTTP消息通信。

因此,本文从讨论HTTP与这二个类开始,然后我将解释一个与本文相关的简单的Web应用。

 

  TheHypertextTransferProtocol(HTTP)

 

  HTTP是一种让Web服务器与浏览器(客户端)通过Internet发送与接收数据的协议。

它是一个请求、响应协议--客户端发出一个请求,服务器响应这个请求。

HTTP运用可靠的TCP连接,通常用的TCP80端口。

它的第一个版本是HTTP/0.9,然后被HTTP/1.0取代。

当前的版本是HTTP/1.1,由RFC2616(.pdf)定义。

 

  本节主要对应HTTP1.1,足够使你充分理解由Web服务器程序发出的消息。

如果你对更加详细的知识有兴趣,可以参考RFC2616。

 

  在HTTP中,客户端总是通过建立一个连接与发送一个HTTP请求来发起一个事务。

服务器不能主动去与客户端联系,也不能给客户端发出一个回叫连接。

客户端与服务器端都可以提前中断一个连接。

例如,当用一个浏览器下载一个文件时,你可以通过点击“停止”键来中断文件的下载,关闭与服务器的HTTP连接。

 

  HTTP请求

 

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

 

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

Requestheader请求头

Entitybody请求实体

 

  下面是一个HTTP请求实例:

 

POST/servlet/default.jspHTTP/1.1

Accept:

text/plain;text/html

Accept-Language:

en-gb

Connection:

Keep-Alive

Host:

localhost

Referer:

http:

//localhost/ch8/SendDetails.htm

User-Agent:

Mozilla/4.0(compatible;MSIE4.01;Windows98)

Content-Length:

33

Content-Type:

application/x-www-form-urlencoded

Accept-Encoding:

gzip,deflate

 

LastName=Franks&FirstName=Michael

 

  TheMethod-URI-Protocol/Version在这个请求的第一行:

 

POST/servlet/default.jspHTTP/1.1

 

  其中POST是请求的类型。

每个客户端HTTP请求可以是HTTP规范中指定的许多请求类型中的一种。

HTTP1.1支持七种类型的请求,它们是GET,POST,HEAD,OPTIONS,PUT,DELETE,TRACE。

其中GET与POST是Internet应用中经常用到的二种请求类型。

 

  URI完整地指定了Internet资源。

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

这样,它应该总是以一个'/'前缀开始。

一个URL实际上是URI的一种类型。

 

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

 

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

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

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

 

  一个非常重要的空行分开了请求头与实体,它标志着实体内容的开始。

一些Internet开发书籍认为这个CRLF空行是HTTP请求的第四个部分。

 

  在上面的HTTP请求中,实体只是简单以下的一行:

 

LastName=Franks&FirstName=Michael

 

  在一个典型的HTTP请求中,请求实体内容会长得多。

 

  HTTP响应

 

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

 

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

Responseheaders响应头

Entitybody响应实体

 

  以下是一个HTTP响应的实例:

 

HTTP/1.1200OK

Server:

Microsoft-IIS/4.0

Date:

Mon,3Jan199813:

13:

33GMT

Content-Type:

text/html

Last-Modified:

Mon,11Jan199813:

23:

42GMT

Content-Length:

112

 

WelcometoBrainySoftware

 

  响应头的第一行类似请求头的第一行,告诉你所用的协议是HTTP1.1,请求成功(200=success),以及没有任何问题。

 

  响应头类似请求头也包含了一些有用的信息。

响应的实体响应本身的HTML内容。

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

 

  Socket类

 

  一个socket是一个网络连接的端点,它使得一个应用可以从网络读与写。

在不同电脑上的二个应用软件能够通过收发字节流而彼此通信。

要发一个信息到另一个应用程序,你需要知道它的IP地址,以及它的socket端口号。

在Java中,一个socket用.Socket来实现。

 

  要创建一个socket,你可以用Socket类中几个构建方法中的一个。

其中一个接受主机名与端口号作为参数:

 

newSocket("",80);

 

  一旦你成功地创建了一个Socket类的实例,你就可以用它去发送与接收字节流了。

要发送字节流,你需要呼叫Socket类的getOutputStream方法来得到一个java.io.OutputSteam对象。

要发送文本到远程的程序,你通常需要从返回的OutputStream创建一个java.io.PrintWriter对象。

要从连接的另一端接收字节流,你需要呼叫Socket类的getInputStream方法,它返回一个java.io.InputStream对象。

 

  以下代码创建一个可以与本地HTTP服务器通信的socket(127.0.0.1表示一个本地的主机),发送一个HTTP请求,并接收从服务器的响应。

它还创建一个StringBuffer对象来接受响应,并打印到控制台。

 

Socketsocket=newSocket("127.0.0.1","8080");

OutputStreamos=socket.getOutputStream();

booleanautoflush=true;

PrintWriterout=newPrintWriter(socket.getOutputStream(),

autoflush);

BufferedReaderin=newBufferedReader(

newInputStreamReader(socket.getInputStream()));

 

//sendanHTTPrequesttothewebserver

out.println("GET/index.jspHTTP/1.1");

out.println("Host:

localhost:

8080");

out.println("Connection:

Close");

out.println();

 

//readtheresponse

booleanloop=true;

StringBuffersb=newStringBuffer(8096);

 

while(loop){

if(in.ready()){

inti=0;

while(i!

=-1){

i=in.read();

sb.append((char)i);

}

loop=false;

}

Thread.currentThread().sleep(50);

}

 

//displaytheresponsetotheoutconsole

System.out.println(sb.toString());

socket.close();

 

  注意要从web服务器得到正确的响应,你必须要发送用HTTP协议编译了的HTTP请求。

如果你看了上面的HTTP部分,你应该能够理解上面代码中的HTTP请求。

 

编者注:

这篇文章节选自budi自己出版的书<Tomcat内幕>。

你可以在他的网站得到更多的相关资料。

 

基于Java的Web服务器工作原理2

作者:

fajaven译发文时间:

2003.09.1217:

00:

38

ServerSocket类

 

  Socket类描述的是“客户端”socket,当你需要创建与远程服务程序连接时需要用到它。

如果你想实现一个服务程序,如HTTP服务器或者FTP服务器,则需要另外不同的方法。

这是因为你的服务器必须随时服务,它不知道什么时候会有一个客户端程序需要连接它。

 

  因为这个目的,你需要用到.ServerSocket这个类,它是服务器端socket的一个实现。

服务器端socket等待来自客户端的连接请求。

一旦它收到一个连接请求,它创建一个socket实例来与客户端进行通信。

 

  要创建服务器端socket,需要用到ServerSocket类提供的四个构建方法中的一个。

你需要指定服务器端socket侦听的IP地址与端口号。

比较典型地,这个IP地址可以是127.0.0.1,意思是该服务器端socket侦听的是本地机器。

服务器端socket侦听的IP地址指的是绑定地址。

服务器端socket另一个重要的属性是队列长度,即它拒绝请求前所接受的最大请求排队长度。

 

  ServerSocket类的构建方法之一如下:

 

publicServerSocket(intport,intbackLog,InetAddressbindingAddress);

 

  对于这个构建方法,绑定地址必须是.InetAddress类的实例。

创建一个InetAddress类的对象的简单方法是呼叫其静态方法getByName,传递一个包含主机名的字符串。

 

InetAddress.getByName("127.0.0.1");

 

  以下行的代码创建了一个服务器端socket,它侦听本地机器的8080端口,限制队列长度为1。

 

newServerSocket(8080,1,InetAddress.getByName("127.0.0.1"));

 

  一旦有了一个ServerSocket实例,就可以通过呼叫其accept方法来让它等待进来的链接请求。

这个方法只有当接收到请求时才返回,它返回的是Socket类的实例。

这个Socket对象就可以用来从客户端应用程序发送与接收字节流,正如上节据说的那样。

实际上,accept方法是本文例子中用到的唯一方法。

 

应用实例

 

  我们的web服务器程序是ex01.pyrmont包的一部分,它包含三个类:

HttpServer;Request;Response。

 

  整个程序的入口(静态main方法)是HttpServer类。

它创建一个HttpServer的实例,并呼叫其await方法。

正如名字表达的,await在一个特定的端口等待HTTP请求,处理它们,并返回响应给客户端。

它保持等待状态,直到收到停止命令。

(用方法名await代替wait,是因为System中有一个重要的与线程相关的方法)

 

  这个程序只从一个特定的目录发送静态资源,如HTML与图像文件。

它只支持没有文件头(如日期与cookie)的情况。

现在我们将在如下的几节中看一下这三个类。

 

HttpServer类

 

  HttpServer实现了一个web服务器,它可以提供(serve)特定目录及其子目录下的静态资源。

这个特定的目录由publicstaticfinalWEB_ROOT指定。

 

  WEB_ROOT初始化如下:

 

publicstaticfinalStringWEB_ROOT=

System.getProperty("user.dir")+File.separator+"webroot";

 

  代码列表中包含了一具叫做webroot的目录,里面有一些静态的资源,你可以用来测试本应用。

你也可以看到一个servlet,在我的下一篇文章将会被用到:

“Servlets容器是怎样工作的”。

 

  为了请求一个静态的资源,在浏览器的地址栏输入如是地址:

http:

//machinename:

port/staticResources

 

  如果你从不同的机器上发送请求到运行本应用的机器,则machinename是运行应用机器的机器名或IP地址,port是8080,staticResources是被请求的文件名称,它必须包含在WEB_ROOT目录内。

 

  例如,如果你用同一台电脑来测试这个应用,你想要HttpServer发送index.html这个文件,用以下的地址:

http:

//localhost:

8080/index.html

 

  要停止服务,只需要从浏览器发送一个停止(shutdown)命令,即在浏览器的地址栏输入host:

port字段后,加上预先定义好的字符串。

在我们的HttpServer类中,停止命令被定义为SHUTDOWN,一个staticfinal变量。

 

privatestaticfinalStringSHUTDOWN_COMMAND="/SHUTDOWN";

 

  因此,要停止服务,你可以这样:

http:

//localhost:

8080/SHUTDOWN

 

  现在,让我们看一下列表1.1中给出的await方法。

代码列表后面将对这段代码做一些解释。

 

Listing1.1.TheHttpServerclass'awaitmethod

 

publicvoidawait(){

ServerSocketserverSocket=null;

intport=8080;

try{

serverSocket=newServerSocket(port,1,

InetAddress.getByName("127.0.0.1"));

}

catch(IOExceptione){

e.printStackTrace();

System.exit

(1);

}

 

//Loopwaitingforarequest

while(!

shutdown){

Socketsocket=null;

InputStreaminput=null;

OutputStreamoutput=null;

try{

socket=serverSocket.accept();

input=socket.getInputStream();

output=socket.getOutputStream();

 

//createRequestobjectandparse

Requestrequest=newRequest(input);

request.parse();

 

//createResponseobject

Responseresponse=newResponse(output);

response.setRequest(request);

response.sendStaticResource();

 

//Closethesocket

socket.close();

 

//checkifthepreviousURIisashutdowncommand

shutdown=request.getUri().equals(SHUTDOWN_COMMAND);

}

catch(Exceptione){

e.printStackTrace();

continue;

}

}

}

 

  await方法以创建一个ServerSocket实例开始,然后进入一个while的循环。

 

serverSocket=newServerSocket(

port,1,InetAddress.getByName("127.0.0.1"));

...

//Loopwaitingforarequest

while(!

shutdown){

...

}

 

  在while循环中的代码,运行到ServerSocket的accept方法即停止。

这个方法只有在8080端口接收到HTTP请求才返回:

 

socket=serverSocket.accept();

 

  收到请求后,await方法从accept方法返回的Socket实例中等到java.io.InputStream与java.io.OutputStream:

 

input=socket.getInputStream();

output=socket.getOutputStream();

 

  然后await方法创建一个Request对象,呼叫它的parse方法来解析这个原始的HTTP请求:

 

//createRequestobjectandparse

Requestrequest=newRequest(input);

request.parse();

 

  下一步,await方法创建一个Response对象并把Request对象设置给它,呼叫它的sendStaticResource方法:

 

//createResponseobject

Responseresponse=newResponse(output);

response.setRequest(request);

response.sendStaticResource();

 

  最后,await方法关闭Socket,呼叫Request的getUri方法来检查HTTP请求的地址是否是一个停止命令。

如果是,则shutdown变量被设置为true,程序退出while循环:

 

//Closethesocket

socket.close();

//checkifthepreviousURIisashutdowncommand

shutdown=request.getUri().equals(SHUTDOWN_COMMAND);

 

基于Java的Web服务器工作原理3

作者:

fajaven发文时间:

2003.09.1217:

11:

54

 

Request类

 

  Request类对应HTTP请求。

创建这个类的实例,并传给它从Socket获得的InputStream对象,从而捕获与客户端的通信。

呼叫InputStream对象的read方法中的一个就可以得到HTTP请求的原始数据。

 

  Request类有二个public方法parse与getUri。

parse方法解析HTTP请求的原始数据。

它做的事情不多--唯一它使之有效的信息是HTTP请求的URI,这个通过呼叫私有方法parseUri来获得。

parseUri方法把URI作为一个变量。

调用getUri方法可以得到HTTP请求的URI。

 

  要明白parse与parseUri的工作原理,你需要知道HTTP请求的结构,由RFC2616定义。

 

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

Requestline;Headers;Messagebody。

 

  现在,我们只需要关注HTTP请求的第一部分--请求行。

请求行以方法记号开始,接着是请求的URI与协议版本,以回车换行符结束。

请求行的元素之间以空格分开。

例如,一个用GET方法的index.html文件的请求行如下:

 

GET/index.htmlHTTP/1.1

 

 

  parse方法从socket的InputStream传递给Request对象中读取字节流,把这个字节数组存在缓冲里。

然后,它把buffer字节数组里的字节放入叫做request的StringBuffer对象中,再把StringBuffer替换成String传递给parseUri方法。

 

  parse方法的代码如列表1.2

 

Listing1.2.TheRequestclass'parsemethod

 

publicvoidparse(){

//Readasetofcharactersfromthesocket

StringBufferrequest=newStringBuffer(2048);

inti;

byte[]buffer=newbyte[2048];

 

try{

i=input.read(buffer);

}

catch(IOExceptione){

e.printStackTrace();

i=-1;

}

 

for(intj=0;jrequest.append((char)buffer[j]);

}

 

System.out.print(request.toString());

uri=parseU

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

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2