阻塞式简易http服务器

  • 说明

        使用java.net包的ServerSocket也是阻塞的,所以下面的实例把ServerSocketChannel换成ServerSocket效果一样。


 

  •  后台代码
  1 package study.socket.tcp.block.httpserver;

  2 

  3 import java.io.FileInputStream;

  4 import java.io.IOException;

  5 import java.net.InetSocketAddress;

  6 import java.net.Socket;

  7 import java.nio.ByteBuffer;

  8 import java.nio.CharBuffer;

  9 import java.nio.channels.FileChannel;

 10 import java.nio.channels.ServerSocketChannel;

 11 import java.nio.channels.SocketChannel;

 12 import java.nio.charset.Charset;

 13 import java.nio.charset.CharsetDecoder;

 14 import java.util.concurrent.ExecutorService;

 15 import java.util.concurrent.Executors;

 16 

 17 /**

 18  * 阻塞式简易http服务器

 19  * @author yj

 20  *

 21  */

 22 public class SimpleHttpServer {

 23 

 24     private int port = 8080;

 25     private ServerSocketChannel serverSocketChannel = null;

 26     private ExecutorService executorService;

 27     private static final int POOL_MULTIPE = 4;

 28     

 29     public SimpleHttpServer() throws Exception {

 30         executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_MULTIPE);

 31         serverSocketChannel = ServerSocketChannel.open();

 32         serverSocketChannel.socket().setReuseAddress(true);

 33         serverSocketChannel.socket().bind(new InetSocketAddress(port));

 34         System.out.println("服务器启动");

 35     }

 36     

 37     public void service() {

 38         while(true) {

 39             System.out.println("服务器接收到客户端请求");

 40             SocketChannel socketChannel = null;

 41             try {

 42                 socketChannel = serverSocketChannel.accept();

 43             } catch (IOException e) {

 44                 e.printStackTrace();

 45             }

 46             executorService.execute(new Handler(socketChannel));

 47             System.out.println("服务端处理完客户端请求");

 48         }

 49     }

 50     

 51     private class Handler implements Runnable {

 52 

 53         private SocketChannel socketChannel;

 54         

 55         public Handler(SocketChannel socketChannel) {

 56             this.socketChannel = socketChannel;

 57         }

 58         

 59         @Override

 60         public void run() {

 61             handler();

 62         }

 63         

 64         private void handler() {

 65             FileInputStream fis = null;

 66             try{

 67                 new Thread().sleep(60000);

 68                 Socket socket = socketChannel.socket();

 69                 System.out.println("接受到客户连接来自:" + socket.getInetAddress() + ":" + socket.getPort());

 70                 ByteBuffer bb = ByteBuffer.allocate(1024);

 71                 socketChannel.read(bb);

 72                 bb.flip();

 73                 String request = decode(bb);

 74                 System.out.println("客户端请求消息:" + request);

 75                 //生成http响应消息

 76                 StringBuffer sb = new StringBuffer("HTTP/1.1 200 OK\r\n");

 77                 sb.append("Content-Type:text/html\r\n\r\n");

 78                 //发送http响应第一行和响应头

 79                 socketChannel.write(encode(sb.toString()));

 80                 

 81                 //获取http请求的第一行

 82                 String firstLineOfRequst = request.substring(0, request.indexOf("\r\n"));

 83                 String filePath = SimpleHttpServer.class.getResource("/").getPath();

 84                 System.out.println("路径:" + filePath);

 85                 System.out.println("测试");

 86                 if(firstLineOfRequst.indexOf("login.html") != -1) {

 87                     fis = new FileInputStream(filePath + "study/socket/block/httpserver/login.html");

 88                 }else {

 89                     fis = new FileInputStream(filePath + "study/socket/block/httpserver/hello.html");

 90                 } 

 91                 FileChannel fc = fis.getChannel();

 92                 fc.transferTo(0, fc.size(), socketChannel);

 93             }catch(Exception e){

 94                 e.printStackTrace();

 95             }finally {

 96                 try {

 97                     if(fis != null) {

 98                         fis.close();

 99                     }

100                     if(socketChannel != null) {

101                         socketChannel.close();

102                     }

103                 } catch (IOException e) {

104                     e.printStackTrace();

105                 }

106             }

107         }

108         

109         private String decode(ByteBuffer bb) throws Exception{

110             Charset charset  =  Charset.forName("utf-8");

111             CharsetDecoder decoder  =  charset.newDecoder();

112             CharBuffer charBuffer  =  decoder.decode(bb);

113             System.out.println( " charBuffer= "   +  charBuffer);

114             System.out.println(charBuffer.toString());

115             System.out.println("编码");

116             return  charBuffer.toString();

117         }

118         

119         private ByteBuffer encode(String str) {

120             System.out.println("解码");

121             return ByteBuffer.wrap(str.getBytes());

122         }

123         

124     }

125     

126     public static void main(String[] args) {

127         try {

128             new SimpleHttpServer().service();

129         } catch (Exception e) {

130             e.printStackTrace();

131         }

132     }

133 }
View Code

  • hello.html文件

        html文件放在类的同级目录下,如果放其他目录下,上面后台代码需要改变取html文件路径。

 1 <!DOCTYPE html>

 2 <html>

 3 <head>

 4 <meta charset="UTF-8">

 5 <title>Insert title here</title>

 6 </head>

 7 <body>

 8     <h1>hello</h1>

 9 </body>

10 </html>
View Code

  • login.html文件

        html文件放在类的同级目录下,如果放其他目录下,上面后台代码需要改变取html文件路径。

 1 <!DOCTYPE html>

 2 <html>

 3 <head>

 4 <meta charset="UTF-8">

 5 <title>Insert title here</title>

 6 </head>

 7 <body>

 8     <h1>login</h1>

 9 </body>

10 </html>
View Code
  • 测试

       浏览器中输入:http://ip:port/或http://ip:port/hello.html访问hello.html,输入:http://ip:port/login.html访问login.html

你可能感兴趣的:(HTTP服务器)