ServerSocket实现 一个简单的Web服务器 [引]

来源:互联网 发布:com域名怎么注册 编辑:程序博客网 时间:2024/06/06 03:18

深入剖析tomcat ch01


项目代码

https://github.com/dzetJavaEE/tomcat_ch01

项目结构

p1.png

请求结果

3.png

打印信息

============== HTTP服务器 运行中...... ==================GET /index.html HTTP/1.1Accept: text/html, application/xhtml+xml, image/jxr, */*Accept-Language: zh-CNUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like GeckoAccept-Encoding: gzip, deflateHost: localhost:8080Connection: Keep-Alive======= 发送至浏览器[客户端] 的静态资源 :D:\___JavaEE\tomcat_ch01\webroot\index.htmlGET /images/logo.gif HTTP/1.1Accept: image/png, image/svg+xml, image/jxr, image/*;q=0.8, */*;q=0.5Referer: http://localhost:8080/index.htmlAccept-Language: zh-CNUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like GeckoAccept-Encoding: gzip, deflateHost: localhost:8080Connection: Keep-Alive======= 发送至浏览器[客户端] 的静态资源 :D:\___JavaEE\tomcat_ch01\webroot\images\logo.gif

HttpServer

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;/** * Http服务器 */public class HttpServer {    /**        WEB_ROOT is the directory where our HTML and other files reside.        For this package, WEB_ROOT is the "webroot" directory under the working directory.        The working directory is the location in the file system from where the java command was invoked.     */    public static final String WEB_ROOT =            System.getProperty("user.dir") + File.separator + "webroot";    // 关机 命令    private static final String SHUTDOWN_COMMAND = "/SHUNTDOWN";    // 收到的关机命令    private boolean shutdown = false;    /**     * 主方法     * @param args     */    public static void main(String[] args) {        HttpServer server = new HttpServer();        server.await();    }    /**     * 等待     */    public void await() {        System.out.println("============== HTTP服务器 运行中...... ==================");        ServerSocket serverSocket = null;        int port = 8080; // 端口        int backlog = 1; // 请求传入连接队列的最大长度。        String host = "127.0.0.1"; // 服务器ip        try {            // 1 创建一个ServerSocket实例,然后进入一个while循环            serverSocket = new ServerSocket(port,backlog, InetAddress.getByName(host));        } catch (IOException e) {            e.printStackTrace();            System.exit(1);        }        // 循环等待一个请求        while (!shutdown){            Socket socket = null;            InputStream input = null;            OutputStream output = null;            try {                // 2 当从8080端口接收到HTTP请求后,ServerSocket类的accept()方法返回,等待结束                socket = serverSocket.accept();                // 2.1 从accept()方法返回的Socket实例中获取InputStream对象 和 OutputStream对象                input = socket.getInputStream();                output = socket.getOutputStream();                // 3 创建一个Request对象,并调用其parse()方法来解析HTTP请求的原始数据                // 创建请求对象和解析                Request request = new Request(input);                request.parse();                // 4 创建一个Response对象,并分别调用其setRequest()方法和sendStaticResource()方法                // 创建响应对象                Response response = new Response(output);                response.setRequest(request);                response.sendStaticResource();                // 5 关闭套接字                // 关闭套接字                socket.close();                // 5.1 调用Request类的getUri()方法来测试HTTP请求的URI是否是关机命令                // 检查上一个URI是否是关机命令                shutdown = request.getUri().equals(SHUTDOWN_COMMAND);            } catch (Exception e) {                e.printStackTrace();            }        }    }}

Request

import java.io.IOException;import java.io.InputStream;/** * HTTP请求 */public class Request {    private InputStream input;    private String uri;    public Request(InputStream input) {        this.input = input;    }    /**     * 解析HTTP请求中的原始数据     * 调用私有方法parseUri() 来解析HTTP请求的URI     */    public void parse() {        // Read a set of characters from the socket        StringBuffer requestStringBuffer = 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++) {            requestStringBuffer.append((char) buffer[j]);        }        String requestString = requestStringBuffer.toString();        System.out.println(requestString);        uri = parseUri(requestString);    }    /**     * 解析HTTP请求的URI,并存储至变量uri     * @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;    }    /**     * 返回HTTP请求的URI     * @return     */    public String getUri() {        return uri;    }}

Response

import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;/*    HTTP Response = Status-Line      *(( general-header | response-header | entity-header ) CRLF)      CRLF      [ message-body ]      Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF *//** * HTTP响应 */public class Response {    /**     * 私有静态常量int BUFFER_SIZE     */    private static final int BUFFER_SIZE = 1024;    /**     * HTTP请求     */    Request request;    /**     * 输出     */    OutputStream output;    public Response(OutputStream output) {        this.output = output;    }    /**     * 设置HTTP请求     *     * @param request     */    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());            System.out.println("======= 发送至浏览器[客户端] 的静态资源 :\n" + file.getPath());            // 文件存在            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) {            System.out.println(e.toString());            e.printStackTrace();        } finally {            if (fis != null) {                fis.close();            }        }    }//    public void setRequest(Request request) {////    }}

index.html

<html><head><title>Welcome to BrainySoftware</title></head><body><img src="./images/logo.gif"><br>Welcome to BrainySoftware.</body></html>

logo.gif

logo.gif


end