简单的 http 服务器
时间:2022-07-24
本文章向大家介绍简单的 http 服务器,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
简单的基于socket和NIO的 http server示例:
项目路径:https://github.com/windwant/windwant-demo/tree/master/httpserver-demo
1. 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 }
2. 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 rn");
49 sb.append("Content-Type: text/htmlrn");
50 sb.append("Content-Length: 24rn" );
51 sb.append("rn" );
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 rn");
75 sb.append("Content-Type: text/htmlrn");
76 sb.append("Content-Length: 24rn" );
77 sb.append("rn" );
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 }
3. 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 }
4. 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 }
- mysql:索引原理与慢查询优化
- Silvelright:ListBox无法用Tab顺序切换内部元素焦点的解决
- 2017精典书店年度好书
- silverlight:贝塞尔曲线
- 三要素支撑“人工智能+安防”:识别技术扛大旗
- IO模型
- jenkins 从git拉取代码
- Silverlight:针式打印机文字模糊的改善办法
- 大数据和云计算技术周报:NoSQL特辑
- 常用业务接口界面化 in python flask
- 打印机设置(PrintDialog)、页面设置(PageSetupDialog) 及 RDLC报表如何选择指定打印机
- 区块链推动支付革命
- MySQL常见的库操作,表操作,数据操作集锦及一些注意事项
- nohup命令
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 为什么GNE 不做全自动提取列表页的功能
- 百度地图开发如何自定义控件(无敌的解决办法)
- 百度地图如何创建一个属于自己的地图,附加到项目中?
- FreeRTOS系列第9篇---FreeRTOS任务概述基础篇
- 图书管理系统(四)图书管理系统实战(2)
- 源码分析之 FactoryBean接口不为人知的秘密
- 图书管理系统(三)图书管理系统实战(1)
- 图书管理系统(二)整合 SSM,你学会了么
- CellChat:细胞间相互作用分析利器
- 我对一类常考算法面试题的详细分析
- Python 面向对象编程(上篇)
- 基于TencentOS-tiny实现PM2.5传感器(攀藤PMSA003)数据解析思路及实现
- Centos7搭建SVN+Apache+iF.SVNAdmin实现web管理SVN
- 安卓最后一个大题复习
- 关于 Spring Ioc,看这一篇就够了!