Die Seite "ex01: 一个简单的 WEB 服务器" wird gelöscht. Bitte seien Sie vorsichtig.
本章介绍 Java Web 服务器是如何运行的。Web 服务器也称为超文本传输协议(HyperText Transfer Protocol, HTTP) 服务器,因为它使用 HTTP 与其它客户端(通常是 Web 浏览器)进行通信。基于 Java 的 Web 服务器会使用两个重要的类:java.net.Socket 类和 java.net.ServerSocket 类,并通过发送 HTTP 消息进行通信。
HTTP 允许 Web 服务服务器和浏览器通过 Internet 发送并接收数据,是一种基于“请求--响应”的协议。HTTP 使用 TCP 连接,TCP 协议默认使用 TCP 80 端口。
一个 HTTP 请求包含以下三部分:
请求示例如下示:
POST /examples/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
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
第一行是请求方法--URI-- 协议/版本,其中 POST 是请求方法,/examples/default.jsp表示 URI,HTTP/1.1 表明请求使用的协议及其版本。
HTTP/1.1 支持 7 种请求方法: GET POST HEAD OPTIONS PUT DELETE TRACE,其中 GET 和 POST 是 Internet 应用中最常用的两种请求方法。
URI 指定 Internet 资源的完整路径。 URI 通常被解释为相对于服务器根目录的相对路径。它总是以 “/”开头。 统一资源定准符(Uniform Resource Locator, URL)实际上是 URI 的一种类型(参见http://www.ietf.org/rfc/rfc2396.txt)。
请求头包含客户端环境和请求实体正文的相关信息。例如,请求头可能会包含浏览器使用的语言,请求实体正文的长度等信息。各个请求头之间用回车/换行(Carriage Return/LineFeed,CRLF) 符间隔开。
在请求头和请求实体正文之间有一个空行,该空行只有 CRLF 符。这个空行对 HTTP 请求格式非常重要。CRLF 告诉 HTTP 服务器请求实体正文从哪里开始。
与 HTTP 请求类似,HTTP 响应也包含三部分:
示例如下:
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Mon, 5 Jan 2004 13:13:33 GMT
Content-Type: text/html
Last-Modified: Mon, 5 Jan 2004 13:13:12 GMT
Content-Length: 112
<html>
<head>
<title>HTTP Response Example</title> </head>
<body>
Welcome to Brainy Software
</body>
</html>
HTTP 响应头的第一行与 HTTP 请求头第一行类似。
套接字是网络连接的端点。套接字应用程序可以从网络中读取数据,可以向网络中写入数据。
要创建一个套接字,可以使用 Socket 类中众多构造函数中的一个。
public Socket(java.lang.String host, int port)
其中参数 host 是远程主机的名称或 IP 地址,参数 port 是连接远程应用程序的端口号。例如,想要通过 80 端口连接 yahoo.com,可以使用下面的语句创建Socket 对象:
new Socket("yahoo.com",80);
一旦成功地创建了 Socket 类的实例,就可以使用该实例发送或接收字节流。要发送字节流,需要调用 Socket 类的 getOutputStream()方法获取一个java.io.OutputStream对象。要发送文本到远程应用程序,通常要使用返回的 OutputSteam 对象创建一个java.io.PrintWriter对象。若想要从连接的另一端接收字节流,需要调用 Socket 类的getInputSteam()方法,该方法会返回一个java.io.InputSteam 对象。
下面的代码创建了一个套接字,用于与本地 HTTP 服务器进行通信(127.0.0.1 表示一个本地主机),发送 HTTP 请求,接收服务器的响应信息。创建了一个 StringBuffer 对象来保存响应信息,并将其输出到控制台上。
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();
`Socket 类表示一个客户端套接字。 ServerSocket 类与 Socket类并不相同。服务器套接字要等待来自客户端的连接请求。当服务器套拉字接收到了连接请求后,它会创建一个 Socket 实例来处理与客户端的通信。
要创建一个服务器套接字,可以使用 ServerSocket 类提供的 4 个构造函数中的任意一个。
public ServerSocket(int port, int backLog, InetAddress bindingAddress);
值得注意的是,在这个构造函数中,参数绑定地址必须是 java.net.InetAddress类的实例。例如侦听本地 8080 端口:
new ServerSocket(8080, 1, InetAddress.getByName("127.0.0.1"));
创建了 ServerSocket 实例后,调用 accept方法可以使其等待传入的连接请求,该连接请求会通过服务器套接字侦听的端口上绑定地址传入。
Die Seite "ex01: 一个简单的 WEB 服务器" wird gelöscht. Bitte seien Sie vorsichtig.