1. 程式人生 > >一個簡單web伺服器的java實現

一個簡單web伺服器的java實現

一個簡單的web伺服器在不考慮其效能及健壯性的情況下,通常只需實現的功能包括伺服器的啟動,它用於監聽某一個埠,接收客戶端發來的請求,並將響應結果返回給客戶端。本文將介紹一個簡單web伺服器的實現原理,它本身只能處理某個目錄下的靜態資原始檔(文字、圖片等)。採用java來實現的話,可以含以下幾個模組,而且各個模組間的關係如圖1所示。


圖1、簡單web伺服器的模組

  •  HttpServer即為伺服器,它用於伺服器的啟動及接收使用者的請求並返回結果;
  • Request:對使用者請求進行分析,解析請求串,並獲取對應的訪問url;
  • Response:根據使用者請求生成響應結果,並將結果輸出給客戶端。

下面通過程式碼來具體的看下該伺服器的實現過程。

HttpServer是伺服器的主實現類,用於關聯Request及Response,原始碼如下所示:
[java] view plaincopyprint?
  1. package com.wow.server;  
  2. import java.io.File;  
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.OutputStream;  
  6. import java.net.InetAddress;  
  7. import java.net.ServerSocket;  
  8. import java.net.Socket;  
  9. import java.net.UnknownHostException;  
  10. /** 
  11.  * 一個簡單的web應用伺服器 
  12.  * @author zhaozheng 
  13.  * 
  14.  */
  15. publicclass HttpServer {  
  16.     publicstaticfinal String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";  
  17.     private
    staticfinal String SHUTDOWN_COMMAND = "/SHUTDOWN";  
  18.     privateboolean shutdown = false;  
  19.     publicstaticvoid main(String[] args) {  
  20.         HttpServer server = new HttpServer();  
  21.         server.start();  
  22.     }  
  23.     //啟動伺服器,並接收使用者請求進行處理
  24.     publicvoid  start() {  
  25.         ServerSocket serverSocket = null;  
  26.         int  PORT = 8080;  
  27.         try {  
  28.             serverSocket = new ServerSocket(PORT, 1, InetAddress.getByName("127.0.0.1"));  
  29.         } catch (UnknownHostException e) {  
  30.             e.printStackTrace();  
  31.             System.exit(-1);  
  32.         } catch (IOException e) {  
  33.             e.printStackTrace();  
  34.             System.exit(-1);  
  35.         }  
  36.         //若請求的命令不為SHUTDOWN時,迴圈處理請求
  37.         while(!shutdown) {  
  38.             Socket socket = null;  
  39.             InputStream input = null;  
  40.             OutputStream output = null;  
  41.             try {  
  42.                 //建立socket進行請求處理
  43.                 socket = serverSocket.accept();  
  44.                 input = socket.getInputStream();  
  45.                 output = socket.getOutputStream();  
  46.                 //接收請求
  47.                 Request request = new Request(input);  
  48.                 request.parser();  
  49.                 //處理請求並返回結果
  50.                 Response response = new Response(output);  
  51.                 response.setRequest(request);  
  52.                 response.sendStaticResource();  
  53.                 //關閉socket
  54.                 socket.close();  
  55.                 //若請求命令為關閉,則關閉伺服器
  56.                 shutdown = request.getUri().equals(SHUTDOWN_COMMAND);  
  57.             } catch (IOException e) {  
  58.                 e.printStackTrace();  
  59.                 continue;  
  60.             }  
  61.         }  
  62.     }  
  63. }  

        該類本身是一個應用程式,包含main方法,直接通過java命令即可執行。在執行時,它本身會啟動一個ServerSocket類用於監聽伺服器的某個埠。當接收到的命令不是停止伺服器的SHUTDOWN時,它會建立一個Socket套接字,用於接收請求及返回響應結果。

        Request類則用於請求的接收,對於Http協議來講,通過瀏覽器向伺服器傳送請求有一定的格式,其實Request也就是接收這些請求資訊,並對其進行分析,抽取出所需的資訊,包括cookie、url等。其中http傳送的請求包括三部分:

  • 請求方法 統一資源識別符號 協議/版本
  • 請求頭
  •  請求實體
其中請求頭與請求實體間有一個空行,具體的示例程式碼如下所示:
[html] view plaincopyprint?
  1. GET /index.htm HTTP/1.1   
  2. Host: www.baidu.com   
  3. Connection: keep-alive   
  4. User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11   
  5. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8   
  6. Accept-Encoding: gzip,deflate,sdch   
  7. Accept-Language: zh-CN,zh;q=0.8 Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3   
  8. Cookie: BAIDUID=D275C16E04D9BB2CF55FD9B9654AECAC:FG=1;   
  9. BDREFER=%7Burl%3A%22http%3A//news.baidu.com/%22%2Cword%3A%22%22%7D;BDUSS=FJ2SzJxSmpKMW1sdVIwMWw3TTBwaHhZRkxFaUdoeG9QLW5GS2dLTUtyZzNhWUpSQVFBQUFBJCQAAAAAAAAAAAouTQytzfcOemhhb3poZW5nNzc1OAAAAAAAAAAAAAAAAAAAAAAAAACAYIArMAAAALCmJHAAAAAA6p5DAAAAAAAxMC4zNi4xNDcblVA3G5VQdBDUT=5b2fD275C16E04D9BB2CF55FD9B9654AECAC138a495329b1MCITY=-%3A; shifen[3113720932]=1357565900; H_PS_PSSID=1445_1661
        Request類用於接收socket套接字傳送過來的位元組流,並按照http協議請求的格式進行解析。對於簡單的web伺服器而言,我們只需要解析出它的uri即可,這樣即可以通過通過檔案匹配的方式找到對應的資源。具體的實現程式碼如下所示:
[java] view plaincopyprint?
  1. package com.wow.server;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. /** 
  5.    *接收到的請求串的具體格式如下: 
  6.    * GET /aaa.htm HTTP/1.1 
  7.    * Host: 127.0.0.1:8080 
  8.    * Connection: keep-alive 
  9.    * User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11 
  10.    * Accept: text/html,application/xhtml+xml,application/xml;q=0.9,q=0.8 
  11.    * Accept-Encoding: gzip,deflate,sdch 
  12.    * Accept-Language: zh-CN,zh;q=0.8 
  13.    * Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3 
  14.    *  
  15.    * @author zhaozheng 
  16.    * 
  17.  */
  18. 相關推薦

    一個簡單web伺服器java實現

    一個簡單的web伺服器在不考慮其效能及健壯性的情況下,通常只需實現的功能包括伺服器的啟動,它用於監聽某一個埠,接收客戶端發來的請求,並將響應結果返回給客戶端。本文將介紹一個簡單web伺服器的實現原理,它本身只能處理某個目錄下的靜態資原始檔(文字、圖片等)。採用java

    go搭建一個簡單web伺服器

    Go語言裡面提供了一個完善的net/http包,通過http包可以很 方便的就搭建起來一個可以執行的web服務。同時使用這個包能很簡單地對web的路由,靜態檔案,模版,cookie等數 據進行設定和操

    【個人學習筆記】Java Web一個簡單的jsp頁面實現輸出100以內的素數

    <%@ page language="java" import="java.util.*" contentType="text/html;charset=utf-8" pageEncoding="utf-8"%> <html> <

    採用Java nio 實現一個簡單伺服器

    伺服器程式碼: package server.nio; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream;

    go語言實現簡單web伺服器

    go語言讓web伺服器實現和部署變得異常簡潔.終於可以拋開亂七八糟的專案結構和體積龐大的IDE,一窺其基本原理. 首先是一個簡單的伺服器實現程式碼,如果是GET請求,則回送一條This is a GET request訊息,如果是POST請求,則解析POST請

    用原生Node實現一個靜態web伺服器

    之前一直用過Apache nginx等靜態web伺服器。 但強大的node.js本身就能作為獨立的web伺服器,不依賴與Apache  nginx 下面我們看看怎麼用Node去寫一個靜態伺服器吧 首先,先來看看我的專案結構吧                  

    自己開發簡單web伺服器一(C++開源庫websocketpp實現

    簡要 Web伺服器主要處理的是HTTP請求(這裡忽略HTTPS),HTTP協議建立在TCP上。如果自己實現,無非就是網路程式設計(socket接受、傳送),資料解析(HTTP欄位解析),返回HTTP協議字串給客戶端等。說起來簡單,要做到跨平臺和高效,不得不介紹幾個有名的開源

    Windows 上靜態編譯 Libevent 2.0.10 並實現一個簡單 HTTP 伺服器

          假設 Visual Studio 2005 的安裝路徑為“D:\Program Files\Microsoft Visual Studio 8\”,Libevent 2.0.10 解壓後的路徑為“D:\libevent-2.0.10-stable”。 編譯生成L

    python uwsgi實現簡單web伺服器(8程式碼)

    python uwsgi實現的簡單web伺服器,一共用了8行程式碼。 先說一下web領域的幾個概念,主要是舉例: web伺服器:apache、iis、nginx等。 web應用伺服器:tomcat、

    C語言實現一個簡單伺服器

    C/S結構流程圖 服務端 socket函式 為了執行網路I/O,一個程序必須做的第一件事情就是建立一個socket函式 /* family 表示協議族 AF_INET(IPv4協議)、AF_INET6(IPv6協議)、AF_L

    自己開發簡單web伺服器二(Node.js實現

    Node.js 剛接觸Node.js沒多久,試用了一下,輕輕鬆鬆幾行程式碼就可以實現一個簡單的HTTP伺服器,開發起來的確比其他語言快多了。 Node.js是一個開源的JavaScript庫,可以跨平臺執行在Windows、Linux、Mac上。JS解析庫用的是大名鼎鼎的G

    利用xinetd實現簡單web伺服器(映象站)

    瀏覽效果: linux伺服器安裝xinetd後,在/etc/xinetd.d/目錄下建立xhttpd檔案,並輸入內容: service xhttpd { socket_type = stream protocol = tcp wait = no

    一個簡單專案看java web 開發的整體佈局

    需求說明: 效果圖: 1:資料庫: 2:匯入資訊頁面: 3:匯入成功後的資料庫: 4:顯示考情資訊(3條): 專案整體格局: 注意:不用管最後一個servlet的包,這個是為了測試,將attenceAction.jsp用se

    c語言實現簡單web伺服器

    浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

    寫了一個簡單輪播效果實現

    char line query span size html ef6 ava top <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

    一個簡單的動態代理實現

    font ima add null 當前 bject tar main style 接口: 1 package spring.aop; 2 3 public interface Arithmetic { 4 5 Integer add(Integer a,In

    簡單選擇排序 java實現

    簡單選擇排序 基本思想:在要排序的一組數中,選出最小的一個數與第一個位置的數交換;然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後一個數比較為止。 程式碼實現如下 public class SimpleSelectSort { publi

    使用XShell 6在Linux上部署web伺服器——java環境的配置

    一、需要用到的軟體及下載連結        1、XShell 6  下載地址: https://www.netsarang.com/download/down_xsh6.html?        

    用flask建立一個簡單web應用

    flask框架,是WSGI的上層封裝實現,使用它,我們完全不用再去了解底層的WSGI的細節了。 第一個flaskweb應用 run.py from flask import Flask # 匯入Flask模組 app = Flask(__name__) # 建立應用例項 @a

    執行一個本地web伺服器

      本文記錄安裝一個Python伺服器的流程。   首先安裝python,地址python.org。確保選中了“將Python 3.xxx新增到PATH”複選框。   進入專案目錄,在終端中輸入python -m http.server以啟動伺服器。預設情況下,這將在本地Web伺服器上的埠8000上執行目