自己实现一个简单的支持并发的Web服务器

前面我们自己实现了一个线程池,现在我们基于前面编写的线程池(http://blog.csdn.net/canot/article/details/50904001)编写一个支持并发访问的Web服务器来处理一些简单的HTTP请求/响应。

public class SimpleHttpServer {
    //定义处理HttpRequest的线程池 
    static ThreadPool<HttpRequestHandler> threadPool = new DefaultThreadPool<HttpRequestHandler>();
    static ServerSocket serverSocket;
    //该Web服务器的路径
    static String basePath;
    //默认的端口号
    static int port = 8080;
  //启动服务器
    public static void start() throws IOException {
        serverSocket = new ServerSocket(port);
        Socket client = null;
        //获取客户端的连接
        while ((client = serverSocket.accept()) != null) {
            //生成一个job放入线程池执行
            threadPool.execute(new HttpRequestHandler(client));
        }
        serverSocket.close();
    }

    static class HttpRequestHandler implements Runnable {
        private Socket client;

        public HttpRequestHandler(Socket client) {
            this.client = client;
        }

        public void run() {
            byte[] buff = new byte[1024];
            BufferedReader br = null;
            PrintWriter pw = null;
            File directory = new File("");
            String basePath = directory.getAbsolutePath();
            int length = 0;
            try {
                //读取客户端发送的请求数据
                br = new BufferedReader(new InputStreamReader(client.getInputStream()));
                //获取请求行的第一行再解析出要请求的资源
                String header = br.readLine();
                String filePath = header.split(" ")[1];
                //判断请求的资源的为html
                if(filePath.endsWith("html")){
                pw = new PrintWriter(client.getOutputStream());
                //构造HTTP响应头信息
                pw.println("HTTP/1.1 200 Ok");
                pw.println("Server: wangxiServer");
                pw.println("Content-Type: text/html;charset=UTF-8");
                pw.println("");
                //通过io流读取访问的资源,然后输出给客户端
                InputStream is = new FileInputStream(new File(basePath,filePath));
                while((length=is.read(buff))>0){
                    pw.println(new String(buff,0,length));
                }
                pw.flush();
                //判断请求的资源的为jpg
                }else if(filePath.endsWith("jpg")){
                    //获取要访问的图片流,把流的数据全部存在ByteArrayOutputStream中
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    InputStream is = new FileInputStream(new File(basePath,filePath));
                    while((length=is.read(buff))>0){
                        bos.write(buff, 0, length);
                    }
                    byte[] image  = bos.toByteArray();
                    //构造HTTP响应头,输出给客户端
                    pw = new PrintWriter(client.getOutputStream());
                    pw.println("HTTP/1.1 200 Ok");
                    pw.println("Server: wangxiServer");
                    pw.println("Content-Type: image/jpeg");
                    pw.println("Content-Length:"+image.length);
                    pw.println("");
                    //输出图片流
                    client.getOutputStream().write(image, 0, image.length);
                }else{
                    pw.println("HTTP/1.1 200 Ok");
                    pw.println("Server: wangxiServer");
                    pw.println("Content-Type: text/html;charset=UTF-8");
                    pw.println("");
                    pw.println("404 No Found");
                    pw.flush();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }
}

启动该服务器:

public class TestMyService {

    public static void main(String[] args) {
        try {
            SimpleHttpServer.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

SimpleHttpServer在建立起与客户端的连接之后,并不会直接处理客户端的请求,而是把其封装成HttpRequestHandler并交给线程池处理。在线程池中则由Worker处理客户端请求的同时,SimpleHttpServer能够继续完成后续客户端连接的建立,并不会阻塞后续客户端的请求。

在该项目的根目录下建立a.html,并放置图片1.jpg:

<html>
<head>
    <title></title>
</head>
<body>
   <img src="http://localhost:8080/1.jpg"></img>
</body>
</html>

在浏览器中输入http://localhost:8080/a.html可以看到图片正常显示,则完成了处理html和jpg的HTTP请求。

你可能感兴趣的:(并发,线程池,web服务器)