简单的 http 服务器

Posted WindWant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单的 http 服务器相关的知识,希望对你有一定的参考价值。

HttpUtils:

  1 package org.windwant.httpserver;
  2 
  3 import java.io.IOException;
  4 import java.net.InetSocketAddress;
  5 import java.net.ServerSocket;
  6 import java.nio.ByteBuffer;
  7 import java.nio.channels.SelectionKey;
  8 import java.nio.channels.Selector;
  9 import java.nio.channels.ServerSocketChannel;
 10 import java.nio.channels.SocketChannel;
 11 import java.util.Iterator;
 12 import java.util.Set;
 13 import java.util.concurrent.ExecutorService;
 14 import java.util.concurrent.Executors;
 15 
 16 /**
 17  * Created by windwant on 2016/6/13.
 18  */
 19 public class HttpNioserver {
 20 
 21     private ServerSocketChannel serverSocketChannel;
 22 
 23     private ServerSocket serverSocket;
 24 
 25     private Selector selector;
 26 
 27     Request request;
 28 
 29     private ExecutorService es;
 30 
 31     private static final Integer SERVER_PORT = 8888;
 32 
 33     public void setShutdown(boolean shutdown) {
 34         this.shutdown = shutdown;
 35     }
 36 
 37     private boolean shutdown = false;
 38 
 39 
 40     public static void main(String[] args) {
 41         HttpNIOServer server = new HttpNIOServer();
 42         server.start();
 43         System.exit(0);
 44     }
 45 
 46     HttpNIOServer(){
 47         try {
 48             es = Executors.newFixedThreadPool(5);
 49             serverSocketChannel = ServerSocketChannel.open();
 50             serverSocketChannel.configureBlocking(false);
 51             serverSocket = serverSocketChannel.socket();
 52             serverSocket.bind(new InetSocketAddress(SERVER_PORT));
 53 
 54             selector = Selector.open();
 55             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
 56             System.out.println("server init...");
 57         } catch (IOException e) {
 58             e.printStackTrace();
 59         }
 60     }
 61 
 62     public void start(){
 63         try {
 64             while (!shutdown){
 65                 selector.select();
 66                 Set<SelectionKey> selectionKeySet = selector.selectedKeys();
 67                 Iterator<SelectionKey> it = selectionKeySet.iterator();
 68                 while (it.hasNext()){
 69                     SelectionKey selectionKey = it.next();
 70                     it.remove();
 71                     handleRequest(selectionKey);
 72                 }
 73             }
 74         } catch (IOException e) {
 75             e.printStackTrace();
 76         }
 77     }
 78 
 79     public void handleRequest(SelectionKey selectionKey){
 80         ServerSocketChannel ssc = null;
 81         SocketChannel ss = null;
 82         try {
 83             if(selectionKey.isAcceptable()){
 84                 ssc = (ServerSocketChannel) selectionKey.channel();
 85                 ss = ssc.accept();
 86 
 87                 ss.configureBlocking(false);
 88                 ss.register(selector, SelectionKey.OP_READ);
 89             }else if(selectionKey.isReadable()){
 90                 ss = (SocketChannel) selectionKey.channel();
 91                 ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
 92                 StringBuffer sb = new StringBuffer();
 93                 while (ss.read(byteBuffer) > 0){
 94                     byteBuffer.flip();
 95                     int lgn = byteBuffer.limit();
 96                     for (int i = 0; i < lgn; i++) {
 97                         sb.append((char)byteBuffer.get(i));
 98                     }
 99                     byteBuffer.clear();
100                 }
101                 if(sb.length() > 0) {
102                     request = new Request();
103                     request.takeUri(sb);
104                     ss.register(selector, SelectionKey.OP_WRITE);
105                 }
106             }else if(selectionKey.isWritable()){
107                 ss = (SocketChannel) selectionKey.channel();
108                 ByteBuffer rb = ByteBuffer.allocate(2048);
109                 Response response = new Response(ss);
110                 response.setRequest(request);
111                 response.responseNIO();
112                 ss.register(selector, SelectionKey.OP_READ);
113             }
114         } catch (IOException e) {
115             e.printStackTrace();
116         }
117     }
118 }

Request:

 1 package org.windwant.httpserver;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 
 6 /**
 7  * Created by windwant on 2016/6/12.
 8  */
 9 public class Request {
10 
11     private InputStream in;
12 
13     public String getUri() {
14         return uri;
15     }
16 
17     private String uri;
18 
19     public Request(){}
20 
21     public Request(InputStream in){
22         this.in = in;
23     }
24 
25     public void read(){
26         StringBuffer sb = new StringBuffer();
27         int i = 0;
28         byte[] b = new byte[2048];
29         try {
30             i = in.read(b);
31             for (int j = 0; j < i; j++) {
32                 sb.append((char)b[j]);
33             }
34             takeUri(sb);
35         } catch (IOException e) {
36             e.printStackTrace();
37         }
38     }
39 
40     public void takeUri(StringBuffer sb){
41         int i = sb.indexOf(" ");
42         if(i > 0){
43             int j = sb.indexOf(" ", i + 1);
44             if(j > 0){
45                 uri = sb.substring(i + 1, j).toString();
46                 System.out.println("http request uri: " + uri);
47                 if(!(uri.endsWith("/index.html") || uri.endsWith("/test.jpg"))){
48                     uri = "/404.html";
49                     System.out.println("http request uri rewrite: " + uri);
50                 }
51             }
52         }
53     }
54 
55 }

Response:

 1 package org.windwant.httpserver;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.IOException;
 7 import java.io.OutputStream;
 8 import java.nio.ByteBuffer;
 9 import java.nio.channels.SocketChannel;
10 
11 /**
12  * Created by windwant on 2016/6/12.
13  */
14 public class Response {
15     private static final int BUFFER_SIZE = 1024;
16 
17     public void setRequest(Request request) {
18         this.request = request;
19     }
20 
21     Request request;
22 
23     OutputStream out;
24 
25     SocketChannel osc;
26 
27     public Response(OutputStream out){
28         this.out = out;
29     }
30 
31     public Response(SocketChannel osc){
32         this.osc = osc;
33     }
34 
35     public void response(){
36         byte[] b = new byte[BUFFER_SIZE];
37         File file = new File(HttpServer.WEB_ROOT, request.getUri());
38         try {
39             StringBuilder sb = new StringBuilder();
40             if(file.exists()){
41                 FileInputStream fi = new FileInputStream(file);
42                 int ch = 0;
43                 while ((ch = fi.read(b, 0, BUFFER_SIZE)) > 0){
44                     out.write(b, 0, ch);
45                 }
46                 out.flush();
47             }else{
48                 sb.append("HTTP/1.1 404 File Not Found \r\n");
49                 sb.append("Content-Type: text/html\r\n");
50                 sb.append("Content-Length: 24\r\n" );
51                 sb.append("\r\n" );
52                 sb.append("<h1>File Not Found!</h1>");
53                 out.write(sb.toString().getBytes());
54             }
55         } catch (FileNotFoundException e) {
56             e.printStackTrace();
57         } catch (IOException e) {
58             e.printStackTrace();
59         }
60     }
61 
62     public void responseNIO(){
63         byte[] b = new byte[BUFFER_SIZE];
64         File file = new File(HttpServer.WEB_ROOT, request.getUri());
65         try {
66             StringBuilder sb = new StringBuilder();
67             if(file != null && file.exists()){
68                 FileInputStream fi = new FileInputStream(file);
69                 while (fi.read(b) > 0){
70                     osc.write(ByteBuffer.wrap(b));
71                     b = new byte[BUFFER_SIZE];
72                 }
73             }else{
74                 sb.append("HTTP/1.1 404 File Not Found \r\n");
75                 sb.append("Content-Type: text/html\r\n");
76                 sb.append("Content-Length: 24\r\n" );
77                 sb.append("\r\n" );
78                 sb.append("<h1>File Not Found!</h1>");
79                 osc.write(ByteBuffer.wrap(sb.toString().getBytes()));
80             }
81         } catch (FileNotFoundException e) {
82             e.printStackTrace();
83         } catch (IOException e) {
84             e.printStackTrace();
85         }
86     }
87 
88 }

HttpServer:

 1 package org.windwant.httpserver;
 2 
 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 
10 /**
11  * Created by windwant on 2016/6/12.
12  */
13 public class HttpServer {
14     public static final String WEB_ROOT = System.getProperty("user.dir") + "\\src\\test\\resources\\webroot";
15     public static final int SERVER_PORT = 8888;
16     public static final String SERVER_IP = "127.0.0.1";
17 
18     public static void main(String[] args) {
19         HttpServer httpServer = new HttpServer();
20         httpServer.await();
21     }
22 
23     public void await(){
24         ServerSocket serverSocket = null;
25         try {
26             serverSocket = new ServerSocket(SERVER_PORT, 1, InetAddress.getByName(SERVER_IP));
27             while (true){
28                 Socket socket = serverSocket.accept();
29                 InputStream in = socket.getInputStream();
30                 OutputStream out = socket.getOutputStream();
31                 Request request = new Request(in);
32                 request.read();
33 
34                 Response response = new Response(out);
35                 response.setRequest(request);
36                 response.response();
37                 socket.close();
38             }
39         } catch (IOException e) {
40             e.printStackTrace();
41         }
42     }
43 }

HttpNIOServer:

  1 package org.windwant.httpserver;
  2 
  3 import java.io.IOException;
  4 import java.net.InetSocketAddress;
  5 import java.net.ServerSocket;
  6 import java.nio.ByteBuffer;
  7 import java.nio.channels.SelectionKey;
  8 import java.nio.channels.Selector;
  9 import java.nio.channels.ServerSocketChannel;
 10 import java.nio.channels.SocketChannel;
 11 import java.util.Iterator;
 12 import java.util.Set;
 13 import java.util.concurrent.ExecutorService;
 14 import java.util.concurrent.Executors;
 15 
 16 /**
 17  * Created by windwant on 2016/6/13.
 18  */
 19 public class HttpNIOServer {
 20 
 21     private ServerSocketChannel serverSocketChannel;
 22 
 23     private ServerSocket serverSocket;
 24 
 25     private Selector selector;
 26 
 27     Request request;
 28 
 29     private ExecutorService es;
 30 
 31     private static final Integer SERVER_PORT = 8888;
 32 
 33     public void setShutdown(boolean shutdown) {
 34         this.shutdown = shutdown;
 35     }
 36 
 37     private boolean shutdown = false;
 38 
 39 
 40     public static void main(String[] args) {
 41         HttpNIOServer server = new HttpNIOServer();
 42         server.start();
 43         System.exit(0);
 44     }
 45 
 46     HttpNIOServer(){
 47         try {
 48             es = Executors.newFixedThreadPool(5);
 49             serverSocketChannel = ServerSocketChannel.open();
 50             serverSocketChannel.configureBlocking(false);
 51             serverSocket = serverSocketChannel.socket();
 52             serverSocket.bind(new InetSocketAddress(SERVER_PORT));
 53 
 54             selector = Selector.open();
 55             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
 56             System.out.println("server init...");
 57         } catch (IOException e) {
 58             e.printStackTrace();
 59         }
 60     }
 61 
 62     public void start(){
 63         try {
 64             while (!shutdown){
 65                 selector.select();
 66                 Set<SelectionKey> selectionKeySet = selector.selectedKeys();
 67                 Iterator<SelectionKey> it = selectionKeySet.iterator();
 68                 while (it.hasNext()){
 69                     SelectionKey selectionKey = it.next();
 70                     it.remove();
 71                     handleRequest(selectionKey);
 72                 }
 73             }
 74         } catch (IOException e) {
 75             e.printStackTrace();
 76         }
 77     }
 78 
 79     public void handleRequest(SelectionKey selectionKey){
 80         ServerSocketChannel ssc = null;
 81         SocketChannel ss = null;
 82         try {
 83             if(selectionKey.isAcceptable()){
 84                 ssc = (ServerSocketChannel) selectionKey.channel();
 85                 ss = ssc.accept();
 86 
 87                 ss.configureBlocking(false);
 88                 ss.register(selector, SelectionKey.OP_READ);
 89             }else if(selectionKey.isReadable()){
 90                 ss = (SocketChannel) selectionKey.channel();
 91                 ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
 92                 StringBuffer sb = new StringBuffer();
 93                 while (ss.read(byteBuffer) > 0){
 94                     byteBuffer.flip();
 95                     int lgn = byteBuffer.limit();
 96                     for (int i = 0; i < lgn; i++) {
 97                         sb.append((char)byteBuffer.get(i));
 98                     }
 99                     byteBuffer.clear();
100                 }
101                 if(sb.length() > 0) {
102                     request = new Request();
103                     request.takeUri(sb);
104                     ss.register(selector, SelectionKey.OP_WRITE);
105                 }
106             }else if(selectionKey.isWritable()){
107                 ss = (SocketChannel) selectionKey.channel();
108                 ByteBuffer rb = ByteBuffer.allocate(2048);
109                 Response response = new Response(ss);
110                 response.setRequest(request);
111                 response.responseNIO();
112                 ss.register(selector, SelectionKey.OP_READ);
113             }
114         } catch (IOException e) {
115             e.printStackTrace();
116         }
117     }
118 }

项目路径:https://github.com/windwant/http-test

以上是关于简单的 http 服务器的主要内容,如果未能解决你的问题,请参考以下文章

简单的方法来分享/讨论/协作的代码片段?

node 环境下简单web服务器搭建代码

IOS开发-OC学习-常用功能代码片段整理

为啥这段代码会泄露? (简单的代码片段)

HTTP客户端代码片段

Apollo Codegen 没有找到生成代码的操作或片段