简单的 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();
}
}
}

 

上一篇:vue.js 请求数据


下一篇:OpenGL的视图变换、模型变换、投影变换、视口变换