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

楼主
基于Java的Web服务器工作原理1
一个 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
 


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

POST /servlet/default.jsp HTTP/1.1
 


  其中 POST 是请求的类型。每个客户端 HTTP 请求可以是 HTTP 规范中指定的许多请求类型中的一种。HTTP 1.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-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 Response Example</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 类中几个构建方法中的一个。其中一个接受主机名与端口号作为参数:

new Socket("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 对象来接受响应,并打印到控制台。
[CODE]
Socket socket    = new Socket("127.0.0.1", "8080");
OutputStream os   = socket.getOutputStream();
boolean autoflush = true;
PrintWriter out   = new PrintWriter( socket.getOutputStream(),
 autoflush );
BufferedReader in = new BufferedReader(
    new InputStreamReader( socket.getInputStream() ));

// send an HTTP request to the web server
out.println("GET /index.jsp HTTP/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() ) {
        int 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();
  [/CODE]

  注意要从 web 服务器得到正确的响应,你必须要发送用 HTTP 协议编译了的 HTTP 请求。如果你看了上面的 HTTP 部分,你应该能够理解上面代码中的 HTTP 请求。
1楼
这篇是好文,怎么没人看呢

电脑版 Page created in 0.0781 seconds with 4 queries.