前两天,利用线程池技术(ThreadPool)写了个web服务器,其性能当然无法和apache iis等相比,但基本的功能都有了,唯一欠缺的是无法解析动态页面,采用解释执行(asp模式的)效率太低,如果采用编译执行,要么自己编写一个编译器来编译整个动态页面,要么采用预编译,很复杂
       。。。。
      。。。。
    
现在把代码拿出来晒一晒!由于只是初步的设计所以没有考虑到很多设计模式,代码在优化上很不到位,请各位高手不吝赐教。
MainServer.java 这是主服务文件,也是提供主线程的类,主线程将请求分发给其他业务线程(workerthread)出来
package com.threadpool;
import java.net.ServerSocket;
      public class MainServer
      
      {
      
       
      
       public static int clientCount = 0;
      
       
      
       //ThreadPool threadPool = null;
      
       int port;
      
       PoolManager poolm;
      
       public MainServer(int port)
      
       {
      
        poolm=PoolManager.getInstance();
      
        poolm.creatThreadPool(100, ActionWorker.class);
      
        this.port = port;
      
       }
      
       public void start() throws Exception
      
       {
      
        ServerSocket ss = new ServerSocket(port);
      
        System.out.println("MainServer is starting.....");
      
        
      
        while(true)
      
        {
      
         clientCount++;
      
         poolm.doService(ss.accept());
      
         System.out.println(clientCount+"connections");
      
        }
      
       }
      
       /**
      
        * @param args
      
        * @throws Exception 
      
        */
      
       public static void main(String[] args) throws Exception 
      
       {
      
        // TODO Auto-generated method stub
      
        MainServer server = new MainServer(80);
      
        server.start();
      
       }
      
       
      
      }
    
      PoolManager.java 线程池管理器,该类负责管理线程池,如创建新线程,回收线程等等。
      
      package com.threadpool;
    
import java.net.Socket;
import Pool.ThreadWorker;
      public class PoolManager
      
      {
      
       //singleton pattern
      
       private static PoolManager instance = null;
      
       ThreadPool threadPool = null;
      
       private PoolManager()
      
       {
      
        
      
       }
      
       
      
       public synchronized static PoolManager getInstance()
      
       {
      
        if(instance == null)
      
         instance = new PoolManager();
      
        
      
        return instance;
      
       }
      
       
      
       //create thread pool
      
       public void creatThreadPool(int max, Class<ActionWorker> worker)
      
       {
      
        
      
        try
      
        {
      
         threadPool = new ThreadPool(max, worker);
      
         System.out.println("create a threadpool...");
      
        }
      
        catch (Exception e)
      
        {
      
         // TODO Auto-generated catch block
      
         e.printStackTrace();
      
        }
      
       }
      
       
      
       private WorkerThread getWorker() throws Exception
      
       {   
      
          return threadPool.getWorker();   
      
       }
      
       
      
       public void doService(Object o)
      
       {   
      
        try
      
        {
      
         getWorker().wake((Socket)o);
      
         System.out.println(Thread.currentThread().getName());
      
        }
      
        catch (Exception e)
      
        {
      
         // TODO Auto-generated catch block
      
         e.printStackTrace();
      
        }   
      
       }
      
      }
    
WorkerThread.java 业务线程类,负责处理具体的请求。
package com.threadpool;
import java.net.Socket;
      public class WorkerThread extends Thread
      
      {
      
       
      
        private IWorker worker;
      
        private Socket data;
      
        private ThreadPool pool;
      
        WorkerThread(String id, IWorker worker, ThreadPool pool)
      
        {
      
         super(id);
      
         this.worker = worker;
      
         this.pool = pool;
      
         this.data = null;
      
        }
      
        
      
        public synchronized void wake(Socket data)
      
        {
      
         this.data = data;
      
         System.out.println("wake up..." + Thread.currentThread().getName());
      
         notify();
      
        }
      
        
      
        public synchronized void run()
      
        {
      
         //boolean stop = false;
      
         System.out.println("run....");
      
         while(true)
      
         {
      
          if(data == null)
      
          {
      
           try
      
           {
      
            wait();
      
            System.out.println(Thread.currentThread().getName()+"wait...");
      
           }
      
           catch (InterruptedException e)
      
           {
      
            // TODO Auto-generated catch block
      
            e.printStackTrace();
      
            continue;
      
           }
      
          }
      
          
      
          System.out.println(this.getName()+"are working"+Thread.currentThread().getName());
      
          worker.run(data);
      
          data = null;
      
          if(!pool.pushBack(this))
      
           break;
      
        }
      
        
      
       }
      
      }
    
IWorker.java为业务逻辑接口
package com.threadpool;
      public interface IWorker
      
      {
      
       public void run(Object data);
      
      }
    
ActionWorker.java真正干活的那个类,称为业务逻辑类,与j2ee中的javaBean对应。
package com.threadpool;
      import java.io.BufferedReader;
      
      import java.io.IOException;
      
      import java.io.InputStream;
      
      import java.io.InputStreamReader;
      
      import java.io.OutputStream;
      
      import java.io.OutputStreamWriter;
      
      import java.io.PrintWriter;
      
      import java.net.Socket;
    
      public class ActionWorker implements IWorker
      
      {
      
       
      
       public void run(Object data)
      
       {
      
        handleRequest((Socket)data);
      
        
      
       }
      
       
      
       private void handleRequest(Socket s)
      
       {
      
        try
      
        {
      
         InputStream is = s.getInputStream();
      
         OutputStream os = s.getOutputStream();
      
         Request request = new Request(is);
      
         request.parse();
      
      //   // create Response object
      
         Response response = new Response(os);
      
            response.setRequest(request);
      
            response.sendStaticResource();
      
         System.out.println("worker is working..");
      
         MainServer.clientCount--;
      
         //执行完毕后关闭socket,释放线程
      
         s.close();
      
        }
      
        catch(IOException ex)
      
        {
      
         ex.printStackTrace();
      
        }
      
        
      
       }
      
      }
    
Requset.java封装请求的类,主要用于提取被请求的文件
package com.threadpool;
      import java.io.IOException;
      
      import java.io.InputStream;
    
      public class Request
      
      {
      
       private InputStream input;
      
       private String uri;
    
         public Request(InputStream input)
      
         {
      
           this.input = input;
      
         }
      
         //从请求中解析出文件名
      
       public void parse()
      
       {
      
        StringBuffer request = new StringBuffer(2048);
      
           int len;
      
           byte[] buffer = new byte[2048];
      
           try 
      
           {
      
             len = input.read(buffer);
      
           }
      
           catch (IOException e)
      
           {
      
             e.printStackTrace();
      
             len = -1;
      
           }
      
           for (int i=0; i<len; i++)
      
           {
      
             request.append((char) buffer[i]);
      
           }
      
           System.out.print(request.toString());
      
           uri = parseUri(request.toString());
      
         }
      
       //截取请求的文件名
      
         private String parseUri(String requestString)
      
         {
      
           int index1, index2;
      
           index1 = requestString.indexOf(' ');
      
           if (index1 != -1)
      
           {
      
             index2 = requestString.indexOf(' ', index1 + 1);
      
             if (index2 > index1)
      
               return requestString.substring(index1 + 1, index2);
      
           }
      
           return null;
      
         }
    
         public String getUri() 
      
         {
      
           return uri;
      
         }
      
      }
    
Response.java 封装相应流的类
package com.threadpool;
      import java.io.File;
      
      import java.io.FileInputStream;
      
      import java.io.IOException;
      
      import java.io.OutputStream;
    
      public class Response
      
      {
      
       private static final int BUFFER_SIZE = 1024;
      
         public Request request;
      
         public OutputStream output;
    
         public Response(OutputStream output)
      
         {
      
           this.output = output;
      
         }
    
         public void setRequest(Request request)
      
         {
      
           this.request = request;
      
         }
    
         public void sendStaticResource() throws IOException 
      
         {
      
           byte[] bytes = new byte[BUFFER_SIZE];
      
           FileInputStream fis = null;
      
           try 
      
           {
      
              File file = new File(System.getProperty("user.dir")+File.separator+"webroot", request.getUri());
      
              if (file.exists())
      
              {
      
                fis = new FileInputStream(file);
      
                int ch = fis.read(bytes, 0, BUFFER_SIZE);
      
                while (ch!=-1)
      
                {
      
                   output.write(bytes, 0, ch);
      
                   ch = fis.read(bytes, 0, BUFFER_SIZE);
      
                }
      
              }
      
              else 
      
              {
      
                // file not found
      
                String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
      
                  "Content-Type: text/html\r\n" +
      
                  "Content-Length: 23\r\n" +
      
                  "\r\n" +
      
                  "<h1>File Not Found</h1>";
      
                output.write(errorMessage.getBytes());
      
              }
      
           }
      
           catch (Exception e)
      
           {
      
              // thrown if cannot instantiate a File object
      
              System.out.println(e.toString() );
      
           }
      
           finally 
      
           {
      
              if (fis!=null)
      
               fis.close();
      
           }
      
         }
      
      }
    
在class文件夹下建立 webroot文件夹作为网站的根目录,把网页文件放在下面就可以通过 http://localhost/yourfilename 访问了,简单的服务器就写出来了,由于使用了池技术所以其原理更接近于真正的webserver.
ps: apache服务器是用纯c编写的,其实现的复杂程度的确让人难以想象。


 
					 
					