博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阻塞式简易http服务器
阅读量:6120 次
发布时间:2019-06-21

本文共 5633 字,大约阅读时间需要 18 分钟。

  • 说明

        使用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  2  3  4 
5 Insert title here 6 7 8

hello

9 10
View Code

  • login.html文件

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

1  2  3  4 
5 Insert title here 6 7 8

login

9 10
View Code
  • 测试

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

转载于:https://www.cnblogs.com/yuyuj/p/4524585.html

你可能感兴趣的文章
记一次eclipse无法启动的排查过程
查看>>
【转】jmeter 进行java request测试
查看>>
读书笔记--MapReduce 适用场景 及 常见应用
查看>>
SignalR在Xamarin Android中的使用
查看>>
Eclipse和MyEclipse使用技巧--Eclipse中使用Git-让版本管理更简单
查看>>
[转]响应式表格jQuery插件 – Responsive tables
查看>>
8个3D视觉效果的HTML5动画欣赏
查看>>
C#如何在DataGridViewCell中自定义脚本编辑器
查看>>
【linux】crontab定时命令
查看>>
Android UI优化——include、merge 、ViewStub
查看>>
Office WORD如何取消开始工作右侧栏
查看>>
Android Jni调用浅述
查看>>
CodeCombat森林关卡Python代码
查看>>
第一个应用程序HelloWorld
查看>>
(二)Spring Boot 起步入门(翻译自Spring Boot官方教程文档)1.5.9.RELEASE
查看>>
Android Annotation扫盲笔记
查看>>
React 整洁代码最佳实践
查看>>
聊聊架构设计做些什么来谈如何成为架构师
查看>>
Java并发编程73道面试题及答案
查看>>
移动端架构的几点思考
查看>>