Tomcat源码分析(二)--连接处理(二)

2014-11-24 08:41:39 · 作者: · 浏览: 1
> 0) && (curProcessors < maxProcessors)) {
return (newProcessor());
} else {
if (maxProcessors < 0) {
return (newProcessor());
} else {
return (null);
}
}
}

}

接下来由processor.assign(socket); 记住这个方法是异步的,不需要等待HttpProcessor来处理完成,所以HttpConnector才能不间断的传入Http请求,在HttpProcessor里有两个方法比较重要,这两个方法协调处理了由HttpConnector传来的socket:
[java]
synchronized void assign(Socket socket) {

// Wait for the Processor to get the previous Socket
while (available) {
try {
wait();
} catch (InterruptedException e) {
}
}

// Store the newly available Socket and notify our thread
this.socket = socket;
available = true;
notifyAll();

if ((debug >= 1) && (socket != null))
log(" An incoming request is being assigned");

}


private synchronized Socket await() {

// Wait for the Connector to provide a new Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}

// Notify the Connector that we have received this Socket
Socket socket = this.socket;
available = false;
notifyAll();

if ((debug >= 1) && (socket != null))

log(" The incoming request has been awaited");

return (socket);

}
看一下HttpProcessor的run方法:
[java]
public void run() {

// Process requests until we receive a shutdown signal
while (!stopped) {

// Wait for the next socket to be assigned
Socket socket = await();
if (socket == null)
continue;

// Process the request from this socket
try {
process(socket);
} catch (Throwable t) {
log("process.invoke", t);
}

// Finish up this request
connector.recycle(this);

}

// Tell threadStop() we have shut ourselves down successfully
synchronized (threadSync) {
threadSync.notifyAll();
}

}

很明显,在它的run方法一开始便是调用上面的await方法来等待(因为一开始available变量为false),所以HttpProcessor会一直阻塞,直到有线程来唤醒它。当从HttpConnector中调用processor.assign(socket),会把socket传给此HttpProcessor对象,并设置available为true,调用notifyAll()唤醒该processor线程以处理socket。同时,在await方法中又把available设置成false,因此又回到初始状态,即可以重新接受socket。
这里处理socket的方法是process(socket),主要作用有两点,1:解析这个socket,即解析http请求,包括请求方法,请求协议等,以填充request,response对象(是不是很熟悉,在servlet和jsp开发经常用到的request,response对象就是从这里来的)。2:传入request,response对象给和HttpConnector绑定的容器,让容器来调用invoke方法进行处理。process方法主要的代码如下:www.2cto.com
[java]
private void process(Socket socket) {
input = new SocketInputStream(socket.getInputStream(),
connector.getBufferSize());
//解析一下连接的地址,端口什么的
parseConnection(socket);
//解析请求头的第一行,即:方法,协议,uri
parseRequest(input, output);
if (!request.getRequest().getProtocol()
.startsWith("HTTP/0"))
parseHeaders(input);//解析http协议的头部
..............................................
connector.getContainer().invoke(request, response);
.....