一个 Web
服务器也被称为 HTTP
服务器,它通过 HTTP 协议与客户端通信。这个客户端通常指的是 Web 浏览器。一个基于 Java 的 Web
服务器用到二个重要的类,java.net.Socket 与 java.net.ServerSocket ,并通过 HTTP 消息通信。因此,本文从讨论 HTTP 与这二个类开始,然后我将解释一个与本文相关的简单的 Web 应用。
def北方站长站 The Hypertext Transfer Protocol(HTTP)
def北方站长站 HTTP 是一种让 Web
服务器与浏览器(客户端)通过 Internet 发送与接收数据的协议。它是一个请求、响应协议--客户端发出一个请求,
服务器响应这个请求。HTTP 运用可靠的 TCP 连接,通常用的 TCP 80 端口。它的第一个版本是 HTTP/0.9 ,然后被 HTTP/1.0 取代。当前的版本是 HTTP/1.1 ,由 RFC2616(.pdf) 定义。
def北方站长站 本节主要对应 HTTP 1.1 ,足够使你充分理解由 Web
服务器程序发出的消息。如果你对更加详细的知识有兴趣,可以参考 RFC2616 。
def北方站长站 在 HTTP 中,客户端总是通过建立一个连接与发送一个 HTTP 请求来发起一个事务。
服务器不能主动去与客户端联系,也不能给客户端发出一个回叫连接。客户端与
服务器端都可以提前中断一个连接。例如,当用一个浏览器
下载一个文件时,你可以通过点击“停止”键来中断文件的
下载,关闭与
服务器的 HTTP 连接。
def北方站长站 HTTP 请求
def北方站长站 一个 HTTP 请求包含三个部分:
def北方站长站Method-URI-Protocol/Version 方法-地址-版本
def北方站长站Request header 请求头
def北方站长站Entity body 请求实体
def北方站长站def北方站长站 下面是一个 HTTP 请求实例:
def北方站长站POST /servlet/default.JSP HTTP/1.1
def北方站长站Accept: text/plain; text/HTML
def北方站长站Accept-Language: en-gb
def北方站长站Connection: Keep-Alive
def北方站长站Host: localhost
def北方站长站Referer: http://localhost/ch8/SendDetails.htm
def北方站长站User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
def北方站长站Content-Length: 33
def北方站长站Content-Type: application/x-www-form-urlencoded
def北方站长站Accept-Encoding: gzip, deflate
def北方站长站LastName=Franks&FirstName=Michael
def北方站长站def北方站长站 The Method-URI-Protocol/Version 在这个请求的第一行:
def北方站长站POST /servlet/default.JSP HTTP/1.1
def北方站长站def北方站长站 其中 POST 是请求的类型。每个客户端 HTTP 请求可以是 HTTP 规范中指定的许多请求类型中的一种。HTTP 1.1 支持七种类型的请求,它们是 GET,POST,HEAD,OPTIONS,PUT,DELETE,TRACE。其中 GET 与 POST 是 Internet 应用中经常用到的二种请求类型。
def北方站长站 URI 完整地指定了 Internet 资源。一个 URI 通常被解析为相对
服务器的根目录。这样,它应该总是以一个 '/' 前缀开始。一个 URL 实际上是 URI 的一种类型。
def北方站长站 Version 指的是该 HTTP 请求所用到的 HTTP 协议版本。
def北方站长站 请求头包含了客户端环境与请求实体的一些有用的信息。例如它包含浏览器设定的语言、实体的长度等等。每条请求头用回车换行符(CRLF)分开。
def北方站长站 一个非常重要的空行分开了请求头与实体,它标志着实体内容的开始。一些 Internet 开发书籍认为这个 CRLF 空行是 HTTP 请求的第四个部分。
def北方站长站 在上面的 HTTP 请求中,实体只是简单以下的一行:
def北方站长站LastName=Franks&FirstName=Michael
def北方站长站def北方站长站 在一个典型的 HTTP 请求中,请求实体内容会长得多。
def北方站长站 HTTP 响应
def北方站长站 与请求相似,HTTP 响应也由三部分组成:
def北方站长站Protocol-Status code-Description 协议状态 描述代码
def北方站长站Response headers 响应头
def北方站长站Entity body 响应实体
def北方站长站def北方站长站 以下是一个 HTTP 响应的实例:
def北方站长站HTTP/1.1 200 OK
def北方站长站Server: Microsoft-IIS/4.0
def北方站长站Date: Mon, 3 Jan 1998 13:13:33 GMT
def北方站长站Content-Type: text/HTML
def北方站长站Last-Modified: Mon, 11 Jan 1998 13:23:42 GMT
def北方站长站Content-Length: 112
def北方站长站<HTML>
def北方站长站<head>
def北方站长站<title>HTTP Response Example</title></head><body>
def北方站长站Welcome to Brainy Software
def北方站长站</body>
def北方站长站</HTML>
def北方站长站def北方站长站 响应头的第一行类似请求头的第一行,告诉你所用的协议是 HTTP 1.1 ,请求成功(200=success),以及没有任何问题。
def北方站长站 响应头类似请求头也包含了一些有用的信息。响应的实体响应本身的 HTML 内容。头与实体之间由回车换行的空行(CRLF)分开。
def北方站长站 Socket 类
def北方站长站 一个 socket 是一个网络连接的端点,它使得一个应用可以从网络读与写。在不同电脑上的二个应用软件能够通过收发字节流而彼此通信。要发一个信息到另一个应用
程序,你需要知道它的IP地址,以及它的 socket 端口号。在 Java 中,一个 socket 用 java.net.Socket 来实现。
def北方站长站 要创建一个 socket ,你可以用 Socket 类中几个构建方法中的一个。其中一个接受主机名与端口号作为参数:
def北方站长站new Socket("yahoo.com", 80);
def北方站长站def北方站长站 一旦你成功地创建了一个 Socket 类的实例,你就可以用它去发送与接收字节流了。要发送字节流,你需要呼叫 Socket 类的 getOutputStream 方法来得到一个 java.io.OutputSteam 对象。要发送文本到远程的
程序,你通常需要从返回的 OutputStream 创建一个 java.io.PrintWriter 对象。要从连接的另一端接收字节流,你需要呼叫 Socket 类的 getInputStream 方法,它返回一个 java.io.InputStream 对象。
def北方站长站 以下代码创建一个可以与本地 HTTP
服务器通信的 socket (127.0.0.1 表示一个本地的主机),发送一个 HTTP 请求,并接收从
服务器的响应。它还创建一个 StringBuffer 对象来接受响应,并打印到控制台。
def北方站长站Socket socket = new Socket("127.0.0.1", "8080");
def北方站长站OutputStream os = socket.getOutputStream();
def北方站长站boolean autoflush = true;
def北方站长站PrintWriter out = new PrintWriter( socket.getOutputStream(),
def北方站长站autoflush );
def北方站长站BufferedReader in = new BufferedReader(
def北方站长站new InputStreamReader( socket.getInputStream() ));
def北方站长站// send an HTTP request to the web server
def北方站长站out.println("GET /index.JSP HTTP/1.1");
def北方站长站out.println("Host: localhost:8080");
def北方站长站out.println("Connection: Close");
def北方站长站out.println();
def北方站长站// read the response
def北方站长站boolean loop = true;
def北方站长站StringBuffer sb = new StringBuffer(8096);
def北方站长站while (loop) {
def北方站长站if ( in.ready() ) {
def北方站长站int i=0;
def北方站长站while (i!=-1) {
def北方站长站i = in.read();
def北方站长站sb.append((char) i);
def北方站长站}
def北方站长站loop = false;
def北方站长站}
def北方站长站Thread.currentThread().sleep(50);
def北方站长站}
def北方站长站// display the response to the out console
def北方站长站System.out.println(sb.toString());
def北方站长站socket.close();
def北方站长站def北方站长站 注意要从 web
服务器得到正确的响应,你必须要发送用 HTTP 协议编译了的 HTTP 请求。如果你看了上面的 HTTP 部分,你应该能够理解上面代码中的 HTTP 请求。
def北方站长站编者注:这篇文章节选自 budi 自己出版的书<Tomcat 内幕>。你可以在他的网站得到更多的相关资料。
def北方站长站def北方站长站基于Java的Web
服务器工作原理2
def北方站长站作者:fajaven译 发文时间:2003.09.12 17:00:38
def北方站长站ServerSocket 类
def北方站长站 Socket 类描述的是“客户端” socket,当你需要创建与远程服务
程序连接时需要用到它。如果你想实现一个服务
程序,如 HTTP
服务器或者 FTP
服务器,则需要另外不同的方法。这是因为你的
服务器必须随时服务,它不知道什么时候会有一个客户端
程序需要连接它。
def北方站长站 因为这个目的,你需要用到 java.net.ServerSocket 这个类,它是
服务器端 socket 的一个实现。
服务器端 socket 等待来自客户端的连接请求。一旦它收到一个连接请求,它创建一个 socket 实例来与客户端进行通信。
def北方站长站 要创建
服务器端 socket ,需要用到 ServerSocket 类提供的四个构建方法中的一个。你需要指定
服务器端 socket 侦听的 IP 地址与端口号。比较典型地,这个 IP 地址可以是 127.0.0.1 ,意思是该
服务器端 socket 侦听的是本地机器。
服务器端 socket 侦听的 IP 地址指的是绑定地址。
服务器端 socket 另一个重要的属性是队列长度,即它拒绝请求前所接受的最大请求排队长度。
def北方站长站 ServerSocket 类的构建方法之一如下:
def北方站长站public ServerSocket(int port,int backLog,InetAddress bindingAddress);
def北方站长站def北方站长站 对于这个构建方法,绑定地址必须是 java.net.InetAddress 类的实例。创建一个 InetAddress 类的对象的简单方法是呼叫其静态方法 getByName ,传递一个包含主机名的字符串。
def北方站长站InetAddress.getByName("127.0.0.1");
def北方站长站def北方站长站 以下行的代码创建了一个
服务器端 socket ,它侦听本地机器的 8080 端口,限制队列长度为 1 。
def北方站长站new ServerSocket(8080,1,InetAddress.getByName("127.0.0.1"));
def北方站长站def北方站长站 一旦有了一个 ServerSocket 实例,就可以通过呼叫其 accept 方法来让它等待进来的链接请求。这个方法只有当接收到请求时才返回,它返回的是 Socket 类的实例。这个 Socket 对象就可以用来从客户端应用
程序发送与接收字节流,正如上节据说的那样。实际上,accept
def北方站长站
共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面