标签:
(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