标签:
(1)HTTPServer的监听启动
sun.net.httpserver.ServerImpl类中启动了Socket监听,ServerImpl的内部类Dispatch类启动了Http服务器的监听
/* main server listener task */ class Dispatcher implements Runnable { private void handleEvent (Event r) { ExchangeImpl t = r.exchange; HttpConnection c = t.getConnection(); try { if (r instanceof WriteFinishedEvent) { int exchanges = endExchange(); if (terminating && exchanges == 0) { finished = true; } SocketChannel chan = c.getChannel(); LeftOverInputStream is = t.getOriginalInputStream(); if (!is.isEOF()) { t.close = true; } if (t.close || idleConnections.size() >= MAX_IDLE_CONNECTIONS) { c.close(); allConnections.remove (c); } else { if (is.isDataBuffered()) { /* don‘t re-enable the interestops, just handle it */ handle (c.getChannel(), c); } else { /* re-enable interestops */ SelectionKey key = c.getSelectionKey(); if (key.isValid()) { key.interestOps ( key.interestOps()|SelectionKey.OP_READ ); } c.time = getTime() + IDLE_INTERVAL; idleConnections.add (c); } } } } catch (IOException e) { logger.log ( Level.FINER, "Dispatcher (1)", e ); c.close(); } } public void run() { while (!finished) { try { /* process the events list first */ while (resultSize() > 0) { Event r; synchronized (lolock) { r = events.remove(0); handleEvent (r); } } selector.select(1000); /* process the selected list now */ Set<SelectionKey> selected = selector.selectedKeys(); Iterator<SelectionKey> iter = selected.iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); iter.remove (); if (key.equals (listenerKey)) { if (terminating) { continue; } SocketChannel chan = schan.accept(); if (chan == null) { continue; /* cancel something ? */ } chan.configureBlocking (false); SelectionKey newkey = chan.register (selector, SelectionKey.OP_READ); HttpConnection c = new HttpConnection (); c.selectionKey = newkey; c.setChannel (chan); newkey.attach (c); allConnections.add (c); } else { try { if (key.isReadable()) { boolean closed; SocketChannel chan = (SocketChannel)key.channel(); HttpConnection conn = (HttpConnection)key.attachment(); // interestOps will be restored at end of read key.interestOps (0); handle (chan, conn); } else { assert false; } } catch (IOException e) { HttpConnection conn = (HttpConnection)key.attachment(); logger.log ( Level.FINER, "Dispatcher (2)", e ); conn.close(); } } } } catch (CancelledKeyException e) { logger.log (Level.FINER, "Dispatcher (3)", e); } catch (IOException e) { logger.log (Level.FINER, "Dispatcher (4)", e); } catch (Exception e) { logger.log (Level.FINER, "Dispatcher (7)", e); } } } public void handle (SocketChannel chan, HttpConnection conn) throws IOException { try { Exchange t = new Exchange (chan, protocol, conn); executor.execute (t); } catch (HttpError e1) { logger.log (Level.FINER, "Dispatcher (5)", e1); conn.close(); } catch (IOException e) { logger.log (Level.FINER, "Dispatcher (6)", e); conn.close(); } } } static boolean debug = ServerConfig.debugEnabled (); static synchronized void dprint (String s) { if (debug) { System.out.println (s); } } static synchronized void dprint (Exception e) { if (debug) { System.out.println (e); e.printStackTrace(); } } Logger getLogger () { return logger; }
该类的初始化在sun.net.httpserver.ServerImpl的构造方法当中
ServerImpl (HttpServer wrapper, String protocol, InetSocketAddress addr, int backlog) throws IOException { this.protocol = protocol; this.wrapper = wrapper; this.logger = Logger.getLogger ("com.sun.net.httpserver"); https = protocol.equalsIgnoreCase ("https"); this.address = addr; contexts = new ContextList(); schan = ServerSocketChannel.open(); if (addr != null) { ServerSocket socket = schan.socket(); socket.bind (addr, backlog); bound = true; } selector = Selector.open (); schan.configureBlocking (false); listenerKey = schan.register (selector, SelectionKey.OP_ACCEPT); dispatcher = new Dispatcher(); idleConnections = Collections.synchronizedSet (new HashSet<HttpConnection>()); allConnections = Collections.synchronizedSet (new HashSet<HttpConnection>()); time = System.currentTimeMillis(); timer = new Timer ("server-timer", true); timer.schedule (new ServerTimerTask(), CLOCK_TICK, CLOCK_TICK); events = new LinkedList<Event>(); logger.config ("HttpServer created "+protocol+" "+ addr); }
随后在sun.net.httpserver.ServerImpl类的start方法当中,作为线程被启动
public void start () { if (!bound || started || finished) { throw new IllegalStateException ("server in wrong state"); } if (executor == null) { executor = new DefaultExecutor(); } Thread t = new Thread (dispatcher); started = true; t.start(); }
import com.sun.net.httpserver.HttpServer;
private HttpServer httpServer = null; public final void init() throws IOException { this.executor = Executors.newCachedThreadPool(); final InetSocketAddress sa = new InetSocketAddress("0.0.0.0", 8080); this.httpServer = HttpServer.create(sa, 0); this.httpServer.setExecutor(this.executor); this.httpServer.createContext("/", new HttpServerHandler()); this.httpServer.start(); }
上面是使用JDK内置HttpServer的方法。
在第二篇文章中介绍过返回的默认对象是
sun.net.httpserver.HttpServerImpl对象,该对象是com.sun.net.httpserver.HttpServer对象的子类
public class HttpServerImpl extends HttpServer { ServerImpl server; HttpServerImpl () throws IOException { this (new InetSocketAddress(80), 0); } HttpServerImpl ( InetSocketAddress addr, int backlog ) throws IOException { server = new ServerImpl (this, "http", addr, backlog); }
.............................................
}
该对象又是ServerImpl对象的外观类,提供了HttpServer的方法,封装了ServerImpl自身的各种方法实现
最终在应用中调用this.httpserver.start()
本质上调用的就是sun.net.httpserver.ServerImpl对象的start()方法
---------------------------------------------------------------------------------------------------------------------------------------
下面分析下Dispatcher类中run方法的监听过程
public void run() {
//server的关闭标志,在调用httpserver.stop()方法后--->即ServerImpl类的stop()方法,设置finished为true(初始化为false) while (!finished) { try { /* process the events list first */ //由于支持HTTP1.1的原因,在一次发送数据结束之后,并不是立即关闭连接和socket,而是将发送完成作为一个事件传递过来,根据上下文决定是否关闭连接 while (resultSize() > 0) { Event r; synchronized (lolock) { r = events.remove(0); handleEvent (r); } } selector.select(1000); /* process the selected list now */ Set<SelectionKey> selected = selector.selectedKeys(); Iterator<SelectionKey> iter = selected.iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); iter.remove (); if (key.equals (listenerKey)) { if (terminating) { continue; } SocketChannel chan = schan.accept(); if (chan == null) { continue; /* cancel something ? */ } chan.configureBlocking (false); SelectionKey newkey = chan.register (selector, SelectionKey.OP_READ); HttpConnection c = new HttpConnection (); c.selectionKey = newkey; c.setChannel (chan); newkey.attach (c); allConnections.add (c); } else { try { if (key.isReadable()) { boolean closed; SocketChannel chan = (SocketChannel)key.channel(); HttpConnection conn = (HttpConnection)key.attachment(); // interestOps will be restored at end of read key.interestOps (0); handle (chan, conn); } else { assert false; } } catch (IOException e) { HttpConnection conn = (HttpConnection)key.attachment(); logger.log ( Level.FINER, "Dispatcher (2)", e ); conn.close(); } } } } catch (CancelledKeyException e) { logger.log (Level.FINER, "Dispatcher (3)", e); } catch (IOException e) { logger.log (Level.FINER, "Dispatcher (4)", e); } catch (Exception e) { logger.log (Level.FINER, "Dispatcher (7)", e); } } }
标签:
原文地址:http://www.cnblogs.com/wuxinliulei/p/4992633.html