[size=medium]
前两天看了Tomcat连接器部分的源码,Tomcat 4默认的连接器随意已经过时了,但是是一个很好的学习工具。它里面用了多线程的机制使得HttpProcesor异步处理。我但是也是看了很长时间,最后大部分看懂了,但是还有很多没有看懂。我自己写了一个很简单的一个连接器HttpConnector,一个HttpProcessor,帮助大家理解它,先看看程序吧。
[/size]
[size=medium]
BootStrap类很简单,就是使得HttpConnector监听socket请求,这个很好理解。
[/size]
[size=medium]
下面是一个比较复杂的HttpConnector类,它首先会创建ServerSocket,然后启动线程,创建minProcessors个HttpProcesor,并使它们都启动起来。
[/size]
[size=medium]
下来一个是HttpProcessor,在线程启动后,会调用await方法,使得当前线程等待,有个Socket请求来临之后,调用assign方法,使得当前线程继续运行,但是assign方法会返回,HttpConnector就可以继续相应请求了。在HttpProcessor处理完了之后,HttpPrcoessor会重新放到栈中,就可以进行复用了。这个来的线程同步感觉看了很久还是明白了,但是我估计
现在还写不出来。
[/size]
[size=medium]
最后贴上客户端程序,这个我们是来测试服务器端运行的,也很好理解。
[/size]
前两天看了Tomcat连接器部分的源码,Tomcat 4默认的连接器随意已经过时了,但是是一个很好的学习工具。它里面用了多线程的机制使得HttpProcesor异步处理。我但是也是看了很长时间,最后大部分看懂了,但是还有很多没有看懂。我自己写了一个很简单的一个连接器HttpConnector,一个HttpProcessor,帮助大家理解它,先看看程序吧。
[/size]
[size=medium]
BootStrap类很简单,就是使得HttpConnector监听socket请求,这个很好理解。
[/size]
public class BootStrap {
public static void main(String[] args){
HttpConnector connector = new HttpConnector();
connector.start();
System.out.println("Server is started, listened in 9999!");
}
}
[size=medium]
下面是一个比较复杂的HttpConnector类,它首先会创建ServerSocket,然后启动线程,创建minProcessors个HttpProcesor,并使它们都启动起来。
[/size]
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Stack;
public class HttpConnector implements Runnable{
private ServerSocket serverSocket;
private int minProcessors = 1;
private int maxProcessors = 5;
private int curProcessors = 0;
private Stack<HttpProcessor> processors = new Stack<HttpProcessor>();
private boolean stopped = false;
public void run() {
try {
while(!stopped){
Socket socket = serverSocket.accept();
HttpProcessor processor = createProcessor();
if(processor != null) {
processor.assign(socket);
} else {
System.out.println("Socket is no resource to be handled!");
}
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void recycle(HttpProcessor processor){
processors.push(processor);
}
public void start(){
try {
serverSocket = new ServerSocket(9999);
} catch (IOException e) {
e.printStackTrace();
}
Thread thread = new Thread(this);
thread.start();
while(curProcessors < minProcessors){
if(maxProcessors > 0 && curProcessors >= maxProcessors){
break;
}
HttpProcessor processor = newProcessor();
processors.push(processor);
}
}
private HttpProcessor newProcessor() {
HttpProcessor processor = new HttpProcessor(this,curProcessors++);
processor.start();
return processor;
}
private HttpProcessor createProcessor(){
synchronized(processors){
if(processors.size() > 0){
return processors.pop();
} else {
if(maxProcessors > 0 && curProcessors < maxProcessors){
return newProcessor();
} else {
if(maxProcessors < 0){
return newProcessor();
} else {
return null;
}
}
}
}
}
}
[size=medium]
下来一个是HttpProcessor,在线程启动后,会调用await方法,使得当前线程等待,有个Socket请求来临之后,调用assign方法,使得当前线程继续运行,但是assign方法会返回,HttpConnector就可以继续相应请求了。在HttpProcessor处理完了之后,HttpPrcoessor会重新放到栈中,就可以进行复用了。这个来的线程同步感觉看了很久还是明白了,但是我估计
现在还写不出来。
[/size]
import java.net.Socket;
public class HttpProcessor implements Runnable{
private HttpConnector connector;
private int processorId;
private Socket socket;
private boolean avaliable = false;
private boolean stopped = false;
public HttpProcessor(HttpConnector connector, int processorId){
this.connector = connector;
this.processorId = processorId;
}
public void run(){
while(!stopped){
Socket socket = await();
process(socket);
connector.recycle(this);
}
}
public void process(Socket socket){
System.out.println("Processor " + processorId + " Process socket :" + socket.getPort());
}
public void start(){
Thread thread = new Thread(this);
thread.start();
}
public synchronized Socket await(){
while(!avaliable){
try {
System.out.println("Process " + processorId + " is ready!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
avaliable = false;
Socket socket = this.socket;
notifyAll();
return socket;
}
public synchronized void assign(Socket socket){
while(avaliable){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
avaliable = true;
this.socket = socket;
notifyAll();
}
}
[size=medium]
最后贴上客户端程序,这个我们是来测试服务器端运行的,也很好理解。
[/size]
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args){
for(int i = 0; i < 100; i++){
Socket socket = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
System.out.println("Socket is started, socket id is:" + socket.getPort());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}