Java资源网

| JAVA基础 | 环境配置 | JDBC | 线程技术 | Socket编程 | JavaMail | JAVA与XML | 设计模式 | 技术新闻 | Java认证 | 程序人生 软件下载
| JSP&Servlet | Spring | Struts | Hibernate | JBuilder | Eclipse | WebService | EJB技术 | J2ME开发 | 应用服务器 | JXTA | Ajax
Articles search文章搜索
   关键字:
   类 别:
       
New download 最新下载
· [组件]HTML Parser 1.5
· [教程]WebSphere Studio应用教程
· [组件]JDom 1.0
· [工具]Junit3.8.1
· [教程]EJB编程及J2EE系统架构和设计
· [教程]EJB教程
· [教程]J2EE Tutorial中文版
· [教程]Java编程思想2(英文)
· [教程]java编程思想(完整版)
· [教程]Java网络编程
New articles 最新文章
· 设计移动 Web 服务
· 解析XML的时候完全忽略DTD
· 理解XML Schema XML Schema 初步
· 标签库的深入研究
· 提升JSP应用程序的七大绝招
· 如何使用JDOM对XML文件进行操作
· 处理XML字符串中特殊字符
· 利用Digester把XML转换成为Java对象
· 使用WebService 和RMI远程协作
· 使用Axis开发Web Service程序
Articles top 热门文章
· Eclipse基础--plugin插件安装(6644)
· eclipse+tomcat+lomboz的安装配置说明(4774)
· Java程序员就业前景(4584)
· Windows下JAVA环境变量的设置祥解(3788)
· Tomcat下JSP、Servlet和JavaBean环境的配置(3716)
· 使用links方式安装Eclipse插件(3698)
· 一个老程序员的心理话(3533)
· linux下jdk的安装与配置(3459)
· 初学者入门:Structs中基本配置入门(3334)
· Eclipse 运行命令行参数大全(3084)
您的位置:首页>>Socket编程>>基于Java的Web服务器工作原理(二)
基于Java的Web服务器工作原理(二)
2005-06-09   来源:Matrix-与Java共舞  作者:Matrix-与Java共舞
    Socket 类描述的是“客户端” socket,当你需要创建与远程服务程序连接时需要用到它。如果你想实现一个服务程序,如 HTTP 服务器或者 FTP 服务器,则需要另外不同的方法。这是因为你的服务器必须随时服务,它不知道什么时候会有一个客户端程序需要连接它。
  因为这个目的,你需要用到 java.net.ServerSocket 这个类,它是服务器端 socket 的一个实现。服务器端 socket 等待来自客户端的连接请求。一旦它收到一个连接请求,它创建一个 socket 实例来与客户端进行通信。
  要创建服务器端 socket ,需要用到 ServerSocket 类提供的四个构建方法中的一个。你需要指定服务器端 socket 侦听的 IP 地址与端口号。比较典型地,这个 IP 地址可以是 127.0.0.1 ,意思是该服务器端 socket 侦听的是本地机器。服务器端 socket 侦听的 IP 地址指的是绑定地址。服务器端 socket 另一个重要的属性是队列长度,即它拒绝请求前所接受的最大请求排队长度(which is the maximum queue length for incoming connection requests before the server socket starts to refuse incoming requests)。
  ServerSocket 类的构建方法之一如下:
public ServerSocket(int port, int backLog, InetAddress bindingAddress);
  对于这个构建方法,绑定地址必须是 java.net.InetAddress 类的实例。创建一个 InetAddress 类的对象的简单方法是呼叫其静态方法 getByName ,传递一个包含主机名的字符串。
InetAddress.getByName("127.0.0.1");
  以下行的代码创建了一个服务器端 socket ,它侦听本地机器的 8080 端口,限制队列长度为 1 。
new ServerSocket(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)特定目录及其子目录下的静态资源。这个特定的目录由 public static final WEB_ROOT 指定。
  WEB_ROOT 初始化如下:
public static final String WEB_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 ,一个 static final 变量。
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
  因此,要停止服务,你可以这样:
http://localhost:8080/SHUTDOWN
  现在,让我们看一下列表 1.1 中给出的 await 方法。代码列表后面将对这段代码做一些解释。
Listing 1.1. The HttpServer class' await method

public void await() {
    ServerSocket serverSocket = null;
    int port = 8080;
    try {
        serverSocket =  new ServerSocket(port, 1,
        InetAddress.getByName("127.0.0.1"));
    }
    catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
    }

    // Loop waiting for a request
    while (!shutdown) {
        Socket socket = null;
        InputStream input = null;
        OutputStream output = null;
        try {
            socket = serverSocket.accept();
            input = socket.getInputStream();
            output = socket.getOutputStream();

            // create Request object and parse
            Request request = new Request(input);
            request.parse();

            // create Response object
            Response response = new Response(output);
            response.setRequest(request);
            response.sendStaticResource();

            // Close the socket
            socket.close();

            //check if the previous URI is a shutdown command
            shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
        }
        catch (Exception e) {
            e.printStackTrace();
            continue;
        }
    }
}

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

serverSocket =  new ServerSocket(
     port, 1, InetAddress.getByName("127.0.0.1"));
...
// Loop waiting for a request
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 请求:
// create Request object and parse
Request request = new Request(input);
request.parse();
  下一步,await 方法创建一个 Response 对象并把 Request 对象设置给它,呼叫它的 sendStaticResource 方法:
// create Response object
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();
  最后,await 方法关闭 Socket ,呼叫 Request 的 getUri 方法来检查 HTTP 请求的地址是否是一个停止命令。如果是,则 shutdown 变量被设置为 true ,程序退出 while 循环:
// Close the socket
socket.close();
//check if the previous URI is a shutdown command
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
  --相关文章--
· 调整nbsp;Javanbsp;I Onbsp;性能 (2007-04-13)
· 用Java实现FTP服务器 (2007-04-13)
· 探讨对象次第读写(Serialization) (2007-04-13)
· 彻底明白Java的IO系统 (2007-04-13)
· 使用缓冲IO提高性能 (2007-04-13)
· 两远程客户端之间的通讯原理 (2007-04-13)

版权所有©2005-2006 JAVA资源网 渝ICP备05007591号 虚拟主机 | 关于我们 | 联系方式 | 广告业务 | 网站地图 | 友情链接