使用nio实现简单的httpServer

来源:互联网 发布:java类中定义方法 编辑:程序博客网 时间:2024/06/05 06:58
import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.StringReader;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;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.logging.Level;import java.util.logging.Logger;public class M4 {private static Logger log = Logger.getLogger(M4.class.getName());private static int port = 8080;private static int readBufSize = 512;private static Selector selector;public static void main(String[] args) {try{ServerSocketChannel channel = ServerSocketChannel.open();channel.socket().bind(new InetSocketAddress(port));channel.configureBlocking(false);selector = Selector.open();channel.register(selector, SelectionKey.OP_ACCEPT);}catch(IOException ex) {log.log(Level.SEVERE,ex.getMessage(),ex);return;}while(true){try {if(selector.select() == 0) {continue;}} catch (Exception e) {log.log(Level.SEVERE,e.getMessage(),e);continue;}for(Iterator<SelectionKey> iter = selector.selectedKeys().iterator();iter.hasNext();) {SelectionKey key = iter.next();iter.remove();if(key.isAcceptable()) {connect(key);} else if (key.isReadable()) {read(key);} else if (key.isWritable()) {writer(key);}}}}private static void writer(SelectionKey key) {Session session = (Session)key.attachment();try {if(session.writer() <= 0) {key.cancel();key.channel().close();}} catch (IOException e) {session.close();log.log(Level.INFO,e.getMessage(),e);}}private static void read(SelectionKey key) {Session session = (Session)key.attachment();try {if(session.read() <= 0 ){key.interestOps(SelectionKey.OP_WRITE);}else {if(session.isHeadEnd()) {key.interestOps(SelectionKey.OP_WRITE);}}} catch (IOException e) {session.close();key.cancel();log.log(Level.INFO,e.getMessage(),e);}}private static void connect(SelectionKey key) {ServerSocketChannel channel = (ServerSocketChannel)key.channel();try {SocketChannel client =  channel.accept();client.configureBlocking(false);SelectionKey clientKey = client.register(selector, SelectionKey.OP_READ);clientKey.attach(new Session(client,readBufSize));} catch (IOException e) {log.log(Level.INFO,e.getMessage(),e);}}}class Session {private Logger log = Logger.getLogger(this.getClass().getName());private static final ByteBuffer successHead = ByteBuffer.wrap("HTTP/1.1 200 OK \r\nServer: Simple Server/1.0\r\n\r\n".getBytes());private static final ByteBuffer notFindHead = ByteBuffer.wrap("HTTP/1.1 404 file not find\r\nServer: Simple Server/1.0\r\n\r\n".getBytes());private static String basePath;static{if(File.separatorChar == '/') {basePath = "/media/E/openSource/apache/commons/commons-io-2.1/docs";}else {basePath = "E:/openSource/apache/commons/commons-io-2.1/docs";}}private SocketChannel client;private ByteBuffer readBuf;private boolean headEnd = false;private StringBuilder builder = new StringBuilder();private char[] endCheck = new char[4];private FileChannel outChannel;private ByteBuffer head;Session(SocketChannel client,int readBufSize){this.client = client;readBuf = ByteBuffer.allocate(readBufSize);}public int read() throws IOException {int count = client.read(readBuf);if(count > 0) {readBuf.flip();if(readBuf.hasRemaining()){byte[] buf = new byte[readBuf.limit()];readBuf.get(buf);builder.append(new String(buf));int a = buf.length - 4;if(a >=0 ){if(buf[a++] == '\r' && buf[a++] =='\n' && buf[a++] == '\r' && buf[a++] == '\n') {headEnd();}}else if(!headEnd && builder.length() >= 4) {builder.getChars(builder.length()-4, builder.length(), endCheck, 0);if(endCheck[0] == '\r' && endCheck[1] =='\n' && endCheck[2] == '\r' && endCheck[3] == '\n') {headEnd();}}}readBuf.clear();}return count;}public int writer() throws IOException {if(null == head){return -1;}if(head.hasRemaining()) {return client.write(head);}if(null != outChannel) {readBuf.clear();if(outChannel.read(readBuf) > 0) {readBuf.flip();return client.write(readBuf);}else {close();return -1;}}return -1;}private void headEnd() {System.out.println(builder.toString());headEnd = true;BufferedReader br = null;try {br = new BufferedReader(new StringReader(builder.toString()));String line = br.readLine();String[] strs = line.split(" ");String path = null;if(strs.length > 1) {path = strs[1];}File file = null;if(path.equals("\\") || path.equals("/")) {file = new File(basePath+"/index.html");}else {file = new File(basePath+path);}if(file.exists()) {head = successHead.duplicate();outChannel = new FileInputStream(file).getChannel();}else {head = notFindHead.duplicate();}} catch (IOException e) {log.log(Level.SEVERE,e.getMessage(),e);}finally{if(null != br) {try {br.close();} catch (IOException e) {log.log(Level.SEVERE,e.getMessage(),e);}}}}public String toHeadString() {return builder.toString();}public boolean isHeadEnd() {return headEnd;}public void close() {try {if(client != null && client.isOpen()) {client.close();}} catch (IOException e) {log.log(Level.SEVERE,e.getMessage(),e);}finally{if(null != outChannel && outChannel.isOpen()) {try {outChannel.close();} catch (IOException e) {log.log(Level.SEVERE,e.getMessage(),e);}}}}}


原创粉丝点击