国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

基于Java的Web服務器工作原理(2)

2019-11-18 12:52:00
字體:
來源:轉載
供稿:網友

  ServerSocket 類
  
    Socket 類描述的是“客戶端” socket,當你需要創建與遠程服務程序連接時需要用到它。假如你想實現一個服務程序,如 HTTP 服務器或者 FTP 服務器,則需要另外不同的方法。這是因為你的服務器必須隨時服務,它不知道什么時候會有一個客戶端程序需要連接它。
  
    因為這個目的,你需要用到 java.net.ServerSocket 這個類,它是服務器端 socket 的一個實現。服務器端 socket 等待來自客戶端的連接請求。一旦它收到一個連接請求,它創建一個 socket 實例來與客戶端進行通信。
  
    要創建服務器端 socket ,需要用到 ServerSocket 類提供的四個構建方法中的一個。你需要指定服務器端 socket 偵聽的 ip 地址與端口號。比較典型地,這個 IP 地址可以是 127.0.0.1 ,意思是該服務器端 socket 偵聽的是本地機器。服務器端 socket 偵聽的 IP 地址指的是綁定地址。服務器端 socket 另一個重要的屬性是隊列長度,即它拒絕請求前所接受的最大請求排隊長度。
  
    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.get  

  
  
    代碼列表中包含了一具叫做 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);
  


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 上高县| 个旧市| 望谟县| 马公市| 呼和浩特市| 高阳县| 汶上县| 黄梅县| 曲阜市| 井研县| 郓城县| 通榆县| 同心县| 阳朔县| 绥滨县| 乌苏市| 湛江市| 桐城市| 荥经县| 乌什县| 大城县| 驻马店市| 新晃| 博客| 稷山县| 合川市| 新晃| 长治市| 绥芬河市| 沾化县| 鄂伦春自治旗| 彭山县| 林甸县| 同德县| 壤塘县| 高碑店市| 宝丰县| 扬州市| 海南省| 新巴尔虎右旗| 密云县|