简单的 http 服务器
简单的基于socket和NIO的 http server示例:
项目路径:https://github.com/windwant/windwant-demo/tree/master/httpserver-demo
1. Request:
package org.windwant.httpserver; import java.io.IOException;
import java.io.InputStream; /**
* Created by windwant on 2016/6/12.
*/
public class Request { private InputStream in; public String getUri() {
return uri;
} private String uri; public Request(){} public Request(InputStream in){
this.in = in;
} public void read(){
StringBuffer sb = new StringBuffer();
int i = 0;
byte[] b = new byte[2048];
try {
i = in.read(b);
for (int j = 0; j < i; j++) {
sb.append((char)b[j]);
}
takeUri(sb);
} catch (IOException e) {
e.printStackTrace();
}
} public void takeUri(StringBuffer sb){
int i = sb.indexOf(" ");
if(i > 0){
int j = sb.indexOf(" ", i + 1);
if(j > 0){
uri = sb.substring(i + 1, j).toString();
System.out.println("http request uri: " + uri);
if(!(uri.endsWith("/index.html") || uri.endsWith("/test.jpg"))){
uri = "/404.html";
System.out.println("http request uri rewrite: " + uri);
}
}
}
} }
2. Response:
package org.windwant.httpserver; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; /**
* Created by windwant on 2016/6/12.
*/
public class Response {
private static final int BUFFER_SIZE = 1024; public void setRequest(Request request) {
this.request = request;
} Request request; OutputStream out; SocketChannel osc; public Response(OutputStream out){
this.out = out;
} public Response(SocketChannel osc){
this.osc = osc;
} public void response(){
byte[] b = new byte[BUFFER_SIZE];
File file = new File(HttpServer.WEB_ROOT, request.getUri());
try {
StringBuilder sb = new StringBuilder();
if(file.exists()){
FileInputStream fi = new FileInputStream(file);
int ch = 0;
while ((ch = fi.read(b, 0, BUFFER_SIZE)) > 0){
out.write(b, 0, ch);
}
out.flush();
}else{
sb.append("HTTP/1.1 404 File Not Found \r\n");
sb.append("Content-Type: text/html\r\n");
sb.append("Content-Length: 24\r\n" );
sb.append("\r\n" );
sb.append("<h1>File Not Found!</h1>");
out.write(sb.toString().getBytes());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public void responseNIO(){
byte[] b = new byte[BUFFER_SIZE];
File file = new File(HttpServer.WEB_ROOT, request.getUri());
try {
StringBuilder sb = new StringBuilder();
if(file != null && file.exists()){
FileInputStream fi = new FileInputStream(file);
while (fi.read(b) > 0){
osc.write(ByteBuffer.wrap(b));
b = new byte[BUFFER_SIZE];
}
}else{
sb.append("HTTP/1.1 404 File Not Found \r\n");
sb.append("Content-Type: text/html\r\n");
sb.append("Content-Length: 24\r\n" );
sb.append("\r\n" );
sb.append("<h1>File Not Found!</h1>");
osc.write(ByteBuffer.wrap(sb.toString().getBytes()));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} }
3. HttpServer:
package org.windwant.httpserver; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket; /**
* Created by windwant on 2016/6/12.
*/
public class HttpServer {
public static final String WEB_ROOT = System.getProperty("user.dir") + "\\src\\test\\resources\\webroot";
public static final int SERVER_PORT = 8888;
public static final String SERVER_IP = "127.0.0.1"; public static void main(String[] args) {
HttpServer httpServer = new HttpServer();
httpServer.await();
} public void await(){
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(SERVER_PORT, 1, InetAddress.getByName(SERVER_IP));
while (true){
Socket socket = serverSocket.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
Request request = new Request(in);
request.read(); Response response = new Response(out);
response.setRequest(request);
response.response();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. HttpNIOServer:
package org.windwant.httpserver; import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Created by windwant on 2016/6/13.
*/
public class HttpNIOServer { private ServerSocketChannel serverSocketChannel; private ServerSocket serverSocket; private Selector selector; Request request; private ExecutorService es; private static final Integer SERVER_PORT = 8888; public void setShutdown(boolean shutdown) {
this.shutdown = shutdown;
} private boolean shutdown = false; public static void main(String[] args) {
HttpNIOServer server = new HttpNIOServer();
server.start();
System.exit(0);
} HttpNIOServer(){
try {
es = Executors.newFixedThreadPool(5);
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress(SERVER_PORT)); selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("server init...");
} catch (IOException e) {
e.printStackTrace();
}
} public void start(){
try {
while (!shutdown){
selector.select();
Set<SelectionKey> selectionKeySet = selector.selectedKeys();
Iterator<SelectionKey> it = selectionKeySet.iterator();
while (it.hasNext()){
SelectionKey selectionKey = it.next();
it.remove();
handleRequest(selectionKey);
}
}
} catch (IOException e) {
e.printStackTrace();
}
} public void handleRequest(SelectionKey selectionKey){
ServerSocketChannel ssc = null;
SocketChannel ss = null;
try {
if(selectionKey.isAcceptable()){
ssc = (ServerSocketChannel) selectionKey.channel();
ss = ssc.accept(); ss.configureBlocking(false);
ss.register(selector, SelectionKey.OP_READ);
}else if(selectionKey.isReadable()){
ss = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
StringBuffer sb = new StringBuffer();
while (ss.read(byteBuffer) > 0){
byteBuffer.flip();
int lgn = byteBuffer.limit();
for (int i = 0; i < lgn; i++) {
sb.append((char)byteBuffer.get(i));
}
byteBuffer.clear();
}
if(sb.length() > 0) {
request = new Request();
request.takeUri(sb);
ss.register(selector, SelectionKey.OP_WRITE);
}
}else if(selectionKey.isWritable()){
ss = (SocketChannel) selectionKey.channel();
ByteBuffer rb = ByteBuffer.allocate(2048);
Response response = new Response(ss);
response.setRequest(request);
response.responseNIO();
ss.register(selector, SelectionKey.OP_READ);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
简单的 http 服务器的更多相关文章
- 使用 Nodejs 搭建简单的Web服务器
使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块. ...
- 一个简单的 Web 服务器 [未完成]
最近学习C++,linux和网络编程,想做个小(mini)项目. 就去搜索引擎, 开源中国, Sourceforge上找http server的项目. 好吧,也去了知乎. 知乎上程序员氛围好, ...
- 20145216 20145330 《信息安全系统设计基础》 实验五 简单嵌入式WEB 服务器实验
20145216 20145330 <信息安全系统设计基础> 实验五 简单嵌入式WEB 服务器实验 实验报告封面 实验步骤 1.阅读理解源码 进入/arm2410cl/exp/basic/ ...
- 自己动手模拟开发一个简单的Web服务器
开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...
- 深入剖析tomcat之一个简单的web服务器
这个简单的web服务器包含三个类 HttpServer Request Response 在应用程序的入口点,也就是静态main函数中,创建一个HttpServer实例,然后调用其await()方法. ...
- 20145208《信息安全系统设计基础》实验五 简单嵌入式WEB 服务器实验
20145208<信息安全系统设计基础>实验五 简单嵌入式WEB 服务器实验 20145208<信息安全系统设计基础>实验五 简单嵌入式WEB 服务器实验
- 用Python建立最简单的web服务器
利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令: python -m Web服务器模块 [端口号,默认8000] 例如: python -m ...
- 计算机网络(13)-----java nio手动实现简单的http服务器
java nio手动实现简单的http服务器 需求分析 最近在学习HTTP协议,还是希望动手去做一做,所以就自己实现了一个http服务器,主要功能是将http请求封装httpRequest,通过解析 ...
- 20145210 20145226 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验
20145210 20145226 <信息安全系统设计基础>实验五 简单嵌入式WEB服务器实验 结对伙伴:20145226 夏艺华 实验报告封面 实验目的与要求 · 掌握在ARM开发板实现 ...
- 20145221 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验
20145221 <信息安全系统设计基础>实验五 简单嵌入式WEB服务器实验 实验报告 队友博客:20145326蔡馨熠 实验博客:<信息安全系统设计基础>实验五 简单嵌入式W ...
随机推荐
- Verilog学习笔记简单功能实现(四)...............译码器和编码器
这里以简单的3-8译码器和8-3编码器为例: module decoder3_8(a,out); :]a; :]out; 'b1<<a;/*把最低位的1左移in位(根据in口输入的值)并赋 ...
- InfluxDB学习之InfluxDB的基本操作
InfluxDB提供类SQL语法,如果熟悉SQL的话会非常容易上手.本文就为大家介绍一下InfluxDB的基本操作. InfluxDB提供类SQL语法,如果熟悉SQL的话会非常容易上手. 本文 ...
- 快速熟悉Velocity
果然公司用的东西跟平时学的东西不太一样,我们公司前台页面并不是我们熟悉的.html或者.jsp文件,而是很多人不知道的 .vm文件,其实只要我们理解了jsp文件,vm文件也就是一些基本语法不同而已. ...
- php ci 2.0框架 ORM
很早知道ci出了2.0版本了.这几天正好有项目要用ci开发 虽然项目不大.不过也从开发项目的过程中熟悉了CI框架 因为是个电商项目 本来想用个YII2 的. 封装的虽然厉害不过功能强大 因为另个兄弟坚 ...
- lodash常用方法1--查询
1.find var _ = require('lodash'); var user1 = { name: 'zhangsan', height: 180, weight: 120 }; var us ...
- 关于jQuery里面的选择器
一.JQuery选择器的概述 选择器是JQuery的根基,在JQuery中,对事件处理.遍历DOM和Ajax操作都依赖于选择器. 二.选择器的优势 1.简洁的语法 2.支持CSS1.0到CSS3.0选 ...
- 实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以
通常,我们都是在业务层和界面层使用枚举类型,这能够为我们编程带来便利,但在数据访问层,不使用枚举类型,因为很多数据库都不支持,比如我们现在用的SqlServer2008就不支持枚举类型的列,用的时候也 ...
- (转载)Windows常见性能计数器(较好的说明)
转载地址:http://blog.csdn.net/dfbrt56/article/details/3341591 Windows常见性能计数器 性能计数器(counter)是描述服务器或操作系统性能 ...
- EasyDropDown – 很棒的下拉菜单,含精美主题
EasyDropDown 是一个 jQuery 插件,你可以毫不费力地将简陋的 Select 元素设置为可定制风格的下拉菜单,用于表单或者一般的导航.和著名的下拉插件 Chosen 很像,但是具有自己 ...
- CSS高级选择符
2016-11-07 <css入门经典>第八章 1.属性选择器 选择器 描述 [attribute] 用于选取带有指定属性的元素. [attribute=value] 用于选取带有指定属性 ...