好了,把这两节的思路重新串一下:
首先会先调用HttpConnection的initialize()方法:
org.apache.catalina.connector.http.HttpConnector
/**
* Initialize this connector (create ServerSocket here!)
*/
public void initialize()
throws LifecycleException {
if (initialized)
throw new LifecycleException (
sm.getString("httpConnector.alreadyInitialized"));
this.initialized=true;
Exception eRethrow = null;
// Establish a server socket on the specified port
try {
serverSocket = open();//打开一个serverSocket实例
} catch (IOException ioe) {
log("httpConnector, io problem: ", ioe);
eRethrow = ioe;
} catch (KeyStoreException kse) {
log("httpConnector, keystore problem: ", kse);
eRethrow = kse;
} catch (NoSuchAlgorithmException nsae) {
log("httpConnector, keystore algorithm problem: ", nsae);
eRethrow = nsae;
} catch (CertificateException ce) {
log("httpConnector, certificate problem: ", ce);
eRethrow = ce;
} catch (UnrecoverableKeyException uke) {
log("httpConnector, unrecoverable key: ", uke);
eRethrow = uke;
} catch (KeyManagementException kme) {
log("httpConnector, key management problem: ", kme);
eRethrow = kme;
}
if ( eRethrow != null )
throw new LifecycleException(threadName + ".open", eRethrow);
}
open方法很简单,这里不说!
org.apache.catalina.connector.http.HttpConnector
/**
* Open and return the server socket for this Connector. If an IP
* address has been specified, the socket will be opened only on that
* address; otherwise it will be opened on all addresses.
*
* @exception IOException input/output or network error
* @exception KeyStoreException error instantiating the
* KeyStore from file (SSL only)
* @exception NoSuchAlgorithmException KeyStore algorithm unsupported
* by current provider (SSL only)
* @exception CertificateException general certificate error (SSL only)
* @exception UnrecoverableKeyException internal KeyStore problem with
* the certificate (SSL only)
* @exception KeyManagementException problem in the key management
* layer (SSL only)
*/
private ServerSocket open()
throws IOException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException,
KeyManagementException
{
// Acquire the server socket factory for this Connector
ServerSocketFactory factory = getFactory();
// If no address is specified, open a connection on all addresses
if (address == null) {
log(sm.getString("httpConnector.allAddresses"));
try {
return (factory.createSocket(port, acceptCount));
} catch (BindException be) {
throw new BindException(be.getMessage() + ":" + port);
}
}
// Open a server socket on the specified address
try {
InetAddress is = InetAddress.getByName(address);
log(sm.getString("httpConnector.anAddress", address));
try {
return (factory.createSocket(port, acceptCount, is));
} catch (BindException be) {
throw new BindException(be.getMessage() + ":" + address +
":" + port);
}
} catch (Exception e) {
log(sm.getString("httpConnector.noAddress", address));
try {
return (factory.createSocket(port, acceptCount));
} catch (BindException be) {
throw new BindException(be.getMessage() + ":" + port);
}
}
}
接着会调用start()方法:
org.apache.catalina.connector.http.HttpConnector
/**
* Begin processing requests via this Connector.
*
* @exception LifecycleException if a fatal startup error occurs
*/
public void start() throws LifecycleException {
// Validate and update our current state
if (started)
throw new LifecycleException
(sm.getString("httpConnector.alreadyStarted"));
threadName = "HttpConnector[" + port + "]";
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our background thread
threadStart();//启动线程
// Create the specified minimum number of processors
while (curProcessors < minProcessors) {
if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
break;
HttpProcessor processor = newProcessor();
recycle(processor);
}
}
这里会启动一个线程 threadStart();
org.apache.catalina.connector.http.HttpConnector
/**
* Start the background processing thread.
*/
private void threadStart() {
log(sm.getString("httpConnector.starting"));
thread = new Thread(this, threadName);
thread.setDaemon(true);//设为守护线程
thread.start();//调用run方法
}
org.apache.catalina.connector.http.HttpConnector
public void run() {
// Loop until we receive a shutdown command
while (!stopped) {
// Accept the next incoming connection from the server socket
Socket socket = null;
try {
// if (debug >= 3)
// log("run: Waiting on serverSocket.accept()");
socket = serverSocket.accept();
// if (debug >= 3)
// log("run: Returned from serverSocket.accept()");
if (connectionTimeout > 0)
socket.setSoTimeout(connectionTimeout);
socket.setTcpNoDelay(tcpNoDelay);
} catch (AccessControlException ace) {
log("socket accept security exception", ace);
continue;
} catch (IOException e) {
// if (debug >= 3)
// log("run: Accept returned IOException", e);
try {
// If reopening fails, exit
synchronized (threadSync) {
if (started && !stopped)
log("accept error: ", e);
if (!stopped) {
// if (debug >= 3)
// log("run: Closing server socket");
serverSocket.close();
// if (debug >= 3)
// log("run: Reopening server socket");
serverSocket = open();
}
}
// if (debug >= 3)
// log("run: IOException processing completed");
} catch (IOException ioe) {
log("socket reopen, io problem: ", ioe);
break;
} catch (KeyStoreException kse) {
log("socket reopen, keystore problem: ", kse);
break;
} catch (NoSuchAlgorithmException nsae) {
log("socket reopen, keystore algorithm problem: ", nsae);
break;
} catch (CertificateException ce) {
log("socket reopen, certificate problem: ", ce);
break;
} catch (UnrecoverableKeyException uke) {
log("socket reopen, unrecoverable key: ", uke);
break;
} catch (KeyManagementException kme) {
log("socket reopen, key management problem: ", kme);
break;
}
continue;
}
// Hand this socket off to an appropriate processor
HttpProcessor processor = createProcessor();
if (processor == null) {
try {
log(sm.getString("httpConnector.noProcessor"));
socket.close();
} catch (IOException e) {
;
}
continue;
}
// if (debug >= 3)
// log("run: Assigning socket to processor " + processor);
processor.assign(socket);
// The processor will recycle itself when it finishes
}
// Notify the threadStop() method that we have shut ourselves down
// if (debug >= 3)
// log("run: Notifying threadStop() that we have shut down");
synchronized (threadSync) {
threadSync.notifyAll();
}
}
这时就会为每一个连接上来的用户分配一个HttpProcessor实例,接着启动HttpProcessor实例中的线程方法来获取连接上来的socket实例,然后就调用process方法:
org.apache.catalina.connector.http.HttpConnector
/**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
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();
}
}
其中有一些小细节,在第二节里面都讲过了,这里就不在说了,很简单对吧。世上无难事嘛。那么接下来就是process这个重头级函数了。但是再讲它之前会先分析一下其他内容!
首先会先调用HttpConnection的initialize()方法:
org.apache.catalina.connector.http.HttpConnector
/**
* Initialize this connector (create ServerSocket here!)
*/
public void initialize()
throws LifecycleException {
if (initialized)
throw new LifecycleException (
sm.getString("httpConnector.alreadyInitialized"));
this.initialized=true;
Exception eRethrow = null;
// Establish a server socket on the specified port
try {
serverSocket = open();//打开一个serverSocket实例
} catch (IOException ioe) {
log("httpConnector, io problem: ", ioe);
eRethrow = ioe;
} catch (KeyStoreException kse) {
log("httpConnector, keystore problem: ", kse);
eRethrow = kse;
} catch (NoSuchAlgorithmException nsae) {
log("httpConnector, keystore algorithm problem: ", nsae);
eRethrow = nsae;
} catch (CertificateException ce) {
log("httpConnector, certificate problem: ", ce);
eRethrow = ce;
} catch (UnrecoverableKeyException uke) {
log("httpConnector, unrecoverable key: ", uke);
eRethrow = uke;
} catch (KeyManagementException kme) {
log("httpConnector, key management problem: ", kme);
eRethrow = kme;
}
if ( eRethrow != null )
throw new LifecycleException(threadName + ".open", eRethrow);
}
open方法很简单,这里不说!
org.apache.catalina.connector.http.HttpConnector
/**
* Open and return the server socket for this Connector. If an IP
* address has been specified, the socket will be opened only on that
* address; otherwise it will be opened on all addresses.
*
* @exception IOException input/output or network error
* @exception KeyStoreException error instantiating the
* KeyStore from file (SSL only)
* @exception NoSuchAlgorithmException KeyStore algorithm unsupported
* by current provider (SSL only)
* @exception CertificateException general certificate error (SSL only)
* @exception UnrecoverableKeyException internal KeyStore problem with
* the certificate (SSL only)
* @exception KeyManagementException problem in the key management
* layer (SSL only)
*/
private ServerSocket open()
throws IOException, KeyStoreException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException,
KeyManagementException
{
// Acquire the server socket factory for this Connector
ServerSocketFactory factory = getFactory();
// If no address is specified, open a connection on all addresses
if (address == null) {
log(sm.getString("httpConnector.allAddresses"));
try {
return (factory.createSocket(port, acceptCount));
} catch (BindException be) {
throw new BindException(be.getMessage() + ":" + port);
}
}
// Open a server socket on the specified address
try {
InetAddress is = InetAddress.getByName(address);
log(sm.getString("httpConnector.anAddress", address));
try {
return (factory.createSocket(port, acceptCount, is));
} catch (BindException be) {
throw new BindException(be.getMessage() + ":" + address +
":" + port);
}
} catch (Exception e) {
log(sm.getString("httpConnector.noAddress", address));
try {
return (factory.createSocket(port, acceptCount));
} catch (BindException be) {
throw new BindException(be.getMessage() + ":" + port);
}
}
}
接着会调用start()方法:
org.apache.catalina.connector.http.HttpConnector
/**
* Begin processing requests via this Connector.
*
* @exception LifecycleException if a fatal startup error occurs
*/
public void start() throws LifecycleException {
// Validate and update our current state
if (started)
throw new LifecycleException
(sm.getString("httpConnector.alreadyStarted"));
threadName = "HttpConnector[" + port + "]";
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our background thread
threadStart();//启动线程
// Create the specified minimum number of processors
while (curProcessors < minProcessors) {
if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
break;
HttpProcessor processor = newProcessor();
recycle(processor);
}
}
这里会启动一个线程 threadStart();
org.apache.catalina.connector.http.HttpConnector
/**
* Start the background processing thread.
*/
private void threadStart() {
log(sm.getString("httpConnector.starting"));
thread = new Thread(this, threadName);
thread.setDaemon(true);//设为守护线程
thread.start();//调用run方法
}
org.apache.catalina.connector.http.HttpConnector
public void run() {
// Loop until we receive a shutdown command
while (!stopped) {
// Accept the next incoming connection from the server socket
Socket socket = null;
try {
// if (debug >= 3)
// log("run: Waiting on serverSocket.accept()");
socket = serverSocket.accept();
// if (debug >= 3)
// log("run: Returned from serverSocket.accept()");
if (connectionTimeout > 0)
socket.setSoTimeout(connectionTimeout);
socket.setTcpNoDelay(tcpNoDelay);
} catch (AccessControlException ace) {
log("socket accept security exception", ace);
continue;
} catch (IOException e) {
// if (debug >= 3)
// log("run: Accept returned IOException", e);
try {
// If reopening fails, exit
synchronized (threadSync) {
if (started && !stopped)
log("accept error: ", e);
if (!stopped) {
// if (debug >= 3)
// log("run: Closing server socket");
serverSocket.close();
// if (debug >= 3)
// log("run: Reopening server socket");
serverSocket = open();
}
}
// if (debug >= 3)
// log("run: IOException processing completed");
} catch (IOException ioe) {
log("socket reopen, io problem: ", ioe);
break;
} catch (KeyStoreException kse) {
log("socket reopen, keystore problem: ", kse);
break;
} catch (NoSuchAlgorithmException nsae) {
log("socket reopen, keystore algorithm problem: ", nsae);
break;
} catch (CertificateException ce) {
log("socket reopen, certificate problem: ", ce);
break;
} catch (UnrecoverableKeyException uke) {
log("socket reopen, unrecoverable key: ", uke);
break;
} catch (KeyManagementException kme) {
log("socket reopen, key management problem: ", kme);
break;
}
continue;
}
// Hand this socket off to an appropriate processor
HttpProcessor processor = createProcessor();
if (processor == null) {
try {
log(sm.getString("httpConnector.noProcessor"));
socket.close();
} catch (IOException e) {
;
}
continue;
}
// if (debug >= 3)
// log("run: Assigning socket to processor " + processor);
processor.assign(socket);
// The processor will recycle itself when it finishes
}
// Notify the threadStop() method that we have shut ourselves down
// if (debug >= 3)
// log("run: Notifying threadStop() that we have shut down");
synchronized (threadSync) {
threadSync.notifyAll();
}
}
这时就会为每一个连接上来的用户分配一个HttpProcessor实例,接着启动HttpProcessor实例中的线程方法来获取连接上来的socket实例,然后就调用process方法:
org.apache.catalina.connector.http.HttpConnector
/**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
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();
}
}
其中有一些小细节,在第二节里面都讲过了,这里就不在说了,很简单对吧。世上无难事嘛。那么接下来就是process这个重头级函数了。但是再讲它之前会先分析一下其他内容!