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

小鱼儿 2022-08-21 04:56 260阅读 0赞

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

  1. public class SimpleHttpServer {
  2. //定义处理HttpRequest的线程池
  3. static ThreadPool<HttpRequestHandler> threadPool = new DefaultThreadPool<HttpRequestHandler>();
  4. static ServerSocket serverSocket;
  5. //该Web服务器的路径
  6. static String basePath;
  7. //默认的端口号
  8. static int port = 8080;
  9. //启动服务器
  10. public static void start() throws IOException {
  11. serverSocket = new ServerSocket(port);
  12. Socket client = null;
  13. //获取客户端的连接
  14. while ((client = serverSocket.accept()) != null) {
  15. //生成一个job放入线程池执行
  16. threadPool.execute(new HttpRequestHandler(client));
  17. }
  18. serverSocket.close();
  19. }
  20. static class HttpRequestHandler implements Runnable {
  21. private Socket client;
  22. public HttpRequestHandler(Socket client) {
  23. this.client = client;
  24. }
  25. public void run() {
  26. byte[] buff = new byte[1024];
  27. BufferedReader br = null;
  28. PrintWriter pw = null;
  29. File directory = new File("");
  30. String basePath = directory.getAbsolutePath();
  31. int length = 0;
  32. try {
  33. //读取客户端发送的请求数据
  34. br = new BufferedReader(new InputStreamReader(client.getInputStream()));
  35. //获取请求行的第一行再解析出要请求的资源
  36. String header = br.readLine();
  37. String filePath = header.split(" ")[1];
  38. //判断请求的资源的为html
  39. if(filePath.endsWith("html")){
  40. pw = new PrintWriter(client.getOutputStream());
  41. //构造HTTP响应头信息
  42. pw.println("HTTP/1.1 200 Ok");
  43. pw.println("Server: wangxiServer");
  44. pw.println("Content-Type: text/html;charset=UTF-8");
  45. pw.println("");
  46. //通过io流读取访问的资源,然后输出给客户端
  47. InputStream is = new FileInputStream(new File(basePath,filePath));
  48. while((length=is.read(buff))>0){
  49. pw.println(new String(buff,0,length));
  50. }
  51. pw.flush();
  52. //判断请求的资源的为jpg
  53. }else if(filePath.endsWith("jpg")){
  54. //获取要访问的图片流,把流的数据全部存在ByteArrayOutputStream中
  55. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  56. InputStream is = new FileInputStream(new File(basePath,filePath));
  57. while((length=is.read(buff))>0){
  58. bos.write(buff, 0, length);
  59. }
  60. byte[] image = bos.toByteArray();
  61. //构造HTTP响应头,输出给客户端
  62. pw = new PrintWriter(client.getOutputStream());
  63. pw.println("HTTP/1.1 200 Ok");
  64. pw.println("Server: wangxiServer");
  65. pw.println("Content-Type: image/jpeg");
  66. pw.println("Content-Length:"+image.length);
  67. pw.println("");
  68. //输出图片流
  69. client.getOutputStream().write(image, 0, image.length);
  70. }else{
  71. pw.println("HTTP/1.1 200 Ok");
  72. pw.println("Server: wangxiServer");
  73. pw.println("Content-Type: text/html;charset=UTF-8");
  74. pw.println("");
  75. pw.println("404 No Found");
  76. pw.flush();
  77. }
  78. } catch (IOException e) {
  79. // TODO Auto-generated catch block
  80. e.printStackTrace();
  81. }
  82. }
  83. }
  84. }

启动该服务器:

  1. public class TestMyService {
  2. public static void main(String[] args) {
  3. try {
  4. SimpleHttpServer.start();
  5. } catch (IOException e) {
  6. // TODO Auto-generated catch block
  7. e.printStackTrace();
  8. }
  9. }
  10. }

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

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

  1. <html>
  2. <head>
  3. <title></title>
  4. </head>
  5. <body>
  6. <img src="http://localhost:8080/1.jpg"></img>
  7. </body>
  8. </html>

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

发表评论

表情:
评论列表 (有 0 条评论,260人围观)

还没有评论,来说两句吧...

相关阅读

    相关 一个简单web服务器java实现

    一个简单的web服务器在不考虑其性能及健壮性的情况下,通常只需实现的功能包括服务器的启动,它用于监听某一个端口,接收客户端发来的请求,并将响应结果返回给客户端。本文将介绍一个简