1. 程式人生 > >一個簡單的HTTP伺服器

一個簡單的HTTP伺服器

應用程式的入口在HttpServer類中。main()方法建立一個HttpServer例項,然後呼叫await()方法。伺服器會在指定的埠上等待HTTP請求,對其進行處理,然後傳送響應資訊回客戶端。

package com.forcht.webApplication;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import
java.net.Socket; /** * * @author forcht * 一個Http伺服器 */ public class HttpServer { public static final String WEB_ROOT= System.getProperty("user.dir")+File.separator+"webroot"; private static final String SHUTDOWN_COMMAND="/SHUTDOWN"; private boolean shutdown=false; public
static void main(String[] args) { HttpServer server=new HttpServer(); server.await(); } 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); } while(!shutdown) { Socket socket=null; InputStream input=null; OutputStream output=null; try { socket = serverSocket.accept(); input=socket.getInputStream(); output=socket.getOutputStream(); //將請求交給request處理 Request request=new Request(input); request.parse(); //建立一個response類來響應客戶端 Response response=new Response(output); response.setRequest(request); response.sendStaticResource(); socket.close(); //判斷是或是關閉伺服器的請求 shutdown=request.getUri().equals(SHUTDOWN_COMMAND); } catch (IOException e) { e.printStackTrace(); continue; } } } }

request類

package com.forcht.webApplication;
/**
 * 
 * @author forcht
 *
 */

import java.io.IOException;
import java.io.InputStream;

public class Request {

    private InputStream input;
    private String uri;

    public Request(InputStream input) {
        this.input=input;
    }
    /**
     * 解析請求
     * 只是將請求打印出來
     */
    public void parse() {
        StringBuffer request=new StringBuffer(2048);
        int i;
        byte[] buffer=new byte[2048];
        try {
            i=input.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
            i=-1;
        }
        for(int j=0;j<i;j++) {
            request.append((char)buffer[j]);
        }
        System.out.println(request.toString());
        uri=parseUri(request.toString());
    }
    /**
     * 獲取請求的行中的url
     * @param requestString
     * @return
     */
    private String parseUri(String requestString) {
        int index1,index2;
        index1=requestString.indexOf(' ');
        if (index1!=-1) {
            index2=requestString.indexOf(' ',index1+1);
            if(index2>index1) {
                return requestString.substring(index1+1, index2);
            }
        }
        return null;
    }
    public String getUri() {
        return uri;
    }

}

response類

package com.forcht.webApplication;
/**
 * 
 * @author forcht
 *
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Response {

    private static final int BUFFER_SIZE=1024;
    Request request;
    OutputStream output;

    public Response(OutputStream output) {
        this.output=output;
    }

    public void setRequest(Request request) {
        this.request=request;
    }
    /**
     * 讀取請求的靜態檔案
     * 併發送給客戶端
     * 如果檔案不存在則返回檔案不存在的資訊
     * @throws IOException
     */
    public void sendStaticResource() throws IOException {
        byte[] bytes=new byte[BUFFER_SIZE];
        FileInputStream fis=null;

        try {
            File file=new File(HttpServer.WEB_ROOT,request.getUri());
            if(file.exists()) {
                fis=new FileInputStream(file);
                int ch=fis.read(bytes,0,BUFFER_SIZE);
                while(ch!=-1) {
                    output.write(bytes,0,ch);
                    ch=fis.read(bytes,0,BUFFER_SIZE);
                }
            }else {
                String errorMessage="Http/1.1 404 File Not Found\r\n"+
                            "Content-Type: text/html\r\n"+
                            "Content-Length: 23\r\n"+
                            "\r\n"+
                            "<h1>File Not Found</h1>";
                output.write(errorMessage.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(fis!=null) {
                fis.close();
            }
        }
    }
}

下面進行測試
在工程下建立一個webroot目錄,在該目錄下編寫一個index.html檔案
這裡寫圖片描述
如果請求的檔案不存在則顯示
這裡寫圖片描述

更多原始碼在https://gitee.com/hai_tang/MyTomcat.git