基于Java的Web服务器工作原理(一)

来源:互联网 发布:易语言e4a源码 编辑:程序博客网 时间:2024/06/04 19:34

基于JavaWeb服务器工作原理(一)

翻译作者:-matrix开源技术-fajaven

英文原文:http://www.onjava.com/pub/a/onjava/2003/04/23/java_webserver.html

编者注:这篇文章节选自budi 自己出版的书<Tomcat 内幕>。你可以在他的网站得到更多的相关资料。

 

       一个 Web 服务器也被称为 HTTP 服务器,它通过 HTTP 协议与客户端通信。这个客户端通常指的是 Web 浏览器。一个基于 Java Web 服务器用到二个重要的类,java.net.Socket java.net.ServerSocket ,并通过 HTTP 消息通信。因此,本文从讨论HTTP 与这二个类开始,然后我将解释一个与本文相关的简单的 Web 应用。

 

The Hypertext Transfer Protocol(HTTP)

 

HTTP 是一种让 Web 服务器与浏览器(客户端)通过 Internet 发送与接收数据的协议。它是一个请求、响应协议--客户端发出一个请求,服务器响应这个请求。HTTP 运用可靠的 TCP 连接,通常用的 TCP 80 端口。它的第一个版本是 HTTP/0.9 ,然后被 HTTP/1.0 取代。当前的版本是 HTTP/1.1 ,由  RFC2616(.pdf) 定义。

本节主要对应 HTTP 1.1 ,足够使你充分理解由 Web 服务器程序发出的消息。如果你对更加详细的知识有兴趣,可以参考 RFC2616

HTTP 中,客户端总是通过建立一个连接与发送一个 HTTP 请求来发起一个事务。服务器不能主动去与客户端联系,也不能给客户端发出一个回叫连接。客户端与服务器端都可以提前中断一个连接。例如,当用一个浏览器下载一个文件时,你可以通过点击停止键来中断文件的下载,关闭与服务器的 HTTP 连接。

 

HTTP 请求

 

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

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

Request header  请求头

Entity body  请求实体

下面是一个 HTTP 请求实例:

POST /servlet/default.jsp HTTP/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; MSIE 4.01; Windows 98)

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.jsp HTTP/1.1

其中 POST 是请求的类型。每个客户端HTTP 请求可以是 HTTP 规范中指定的许多请求类型中的一种。HTTP 1.1 支持七种类型的请求,它们是GETPOSTHEADOPTIONSPUTDELETETRACE。其中 GET POST Internet 应用中经常用到的二种请求类型。

URI 完整地指定了 Internet 资源。一个 URI 通常被解析为相对服务器的根目录。这样,它应该总是以一个 '/' 前缀开始。一个 URL 实际上是 URI 的一种类型。

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

 

请求头包含了客户端环境与请求实体的一些有用的信息。例如它包含浏览器设定的语言、实体的长度等等。每条请求头用回车换行符(CRLF)分开。

一个非常重要的空行分开了请求头与实体,它标志着实体内容的开始。一些 Internet 开发书籍认为这个 CRLF 空行是 HTTP 请求的第四个部分。

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

LastName=Franks&FirstName=Michael

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

 

HTTP 响应

 

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

Protocol-Status code-Description  协议状态 描述代码

Response headers  响应头

Entity body  响应实体

 

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

HTTP/1.1 200 OK

Server: Microsoft-IIS/4.0

Date: Mon, 3 Jan 1998 13:13:33 GMT

Content-Type: text/html

Last-Modified: Mon, 11 Jan 1998 13:23:42 GMT

Content-Length: 112

 

<html>

<head>

<title>HTTP ResponseExample</title></head><body>

Welcome to Brainy Software

</body>

</html>

 

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

响应头类似请求头也包含了一些有用的信息。响应的实体响应本身的 HTML 内容。头与实体之间由回车换行的空行(CRLF)分开。

 

Socket

 

一个 socket 是一个网络连接的端点,它使得一个应用可以从网络读与写。在不同电脑上的二个应用软件能够通过收发字节流而彼此通信。要发一个信息到另一个应用程序,你需要知道它的IP地址,以及它的 socket 端口号。在 Java 中,一个 socket java.net.Socket 来实现。

要创建一个 socket ,你可以用 Socket 类中几个构建方法中的一个。其中一个接受主机名与端口号作为参数:

Socket s = newSocket("yahoo.com", 80);

 

一旦你成功地创建了一个 Socket 类的实例,你就可以用它去发送与接收字节流了。要发送字节流,你需要呼叫 Socket 类的 getOutputStream 方法来得到一个 java.io.OutputSteam 对象。要发送文本到远程的程序,你通常需要从返回的 OutputStream 创建一个 java.io.PrintWriter 对象。要从连接的另一端接收字节流,你需要呼叫 Socket 类的 getInputStream 方法,它返回一个 java.io.InputStream 对象。

以下代码创建一个可以与本地 HTTP 服务器通信的 socket(127.0.0.1 表示一个本地的主机),发送一个 HTTP 请求,并接收从服务器的响应。它还创建一个 StringBuffer 对象来接受响应,并打印到控制台。

 

Socket socket    = newSocket("127.0.0.1", "8080");

OutputStream os   =socket.getOutputStream();

boolean autoflush = true;

PrintWriter out   = newPrintWriter( socket.getOutputStream(), autoflush );

BufferedReader in = new BufferedReader(newInputStreamReader( socket.getInputStream() ));

 

// send an HTTP request to the web server

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

out.println("Host:localhost:8080");

out.println("Connection: Close");

out.println();

 

// read the response

boolean loop    = true;

StringBuffer sb = new StringBuffer(8096);

 

while (loop) {

if ( in.ready()) {

i=0;

while (i != -1) {

 i = in.read();

 sb.append((char) i);

}

loop = false;

}

Thread.currentThread().sleep(50);

}

 

// display the response to the out console

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

socket.close();

 

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

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

 

matrix开源技术经Onjava授权翻译并发布。

如果你对此文章有任何看法或建议,请到Matrix论坛发表您的意见。

注明: 如果对matrix的翻译文章系列感兴趣,请点击oreillyjavaworld文章翻译计划查看详细情况。

您也可以点击-fajaven查看翻译作者的详细信息。