java 一个基础的代理服务器类

/************************************* 
  *   一个基础的代理服务器类 
  ************************************* 
  */ 
import   java.net.*; 
import   java.io.*; 

public   class   HttpProxy   extends   Thread   { 
        static   public   int   CONNECT_RETRIES=5; 
        static   public   int   CONNECT_PAUSE=5; 
        static   public   int   TIMEOUT=50; 
        static   public   int   BUFSIZ=1024; 
        static   public   boolean   logging   =   false; 
        static   public   OutputStream   log=null; 
        //   传入数据用的Socket 
        protected   Socket   socket; 
        //   上级代理服务器,可选 
        static   private   String   parent=null; 
        static   private   int   parentPort=-1; 
        static   public   void   setParentProxy(String   name,   int   pport)   { 
parent=name; 
parentPort=pport; 
        } 

        //   在给定Socket上创建一个代理线程。 
        public   HttpProxy(Socket   s)   {   socket=s;   start();   } 

        public   void   writeLog(int   c,   boolean   browser)   throws   IOException   { 
log.write(c); 
        } 

        public   void   writeLog(byte[]   bytes,int   offset,   int   len,   boolean   browser)   throws   IOException   { 
for   (int   i=0;i <len;i++)   writeLog((int)bytes[offset+i],browser); 
        } 


        //   默认情况下,日志信息输出到 
        //   标准输出设备 
        //   派生类可以覆盖它 
        public   String   processHostName(String   url,   String   host,   int   port,   Socket   sock)   { 
java.text.DateFormat   cal=java.text.DateFormat.getDateTimeInstance(); 
System.out.println(cal.format(new   java.util.Date())   +   "   -   "   +   url   +   "   "   
                            +   sock.getInetAddress()+ "\n "); 
return   host; 
        } 


        //   执行操作的线程 
        public   void   run()   { 
String   line; 
String   host; 
int   port=80; 
                Socket   outbound=null; 
try   { 
        socket.setSoTimeout(TIMEOUT); 
        InputStream   is=socket.getInputStream(); 
        OutputStream   os=null; 
        try   { 
                                //   获取请求行的内容 
line= " "; 
host= " "; 
int   state=0; 
boolean   space; 
while   (true)   { 
        int   c=is.read(); 
        if   (c==-1)   break; 
        if   (logging)   writeLog(c,true); 
        space=Character.isWhitespace((char)c);   
        switch   (state)   { 
        case   0: 
if   (space)   continue;   
                state=1; 
        case   1: 
if   (space)   { 
        state=2; 
        continue; 

line=line+(char)c; 
break; 
        case   2: 
if   (space)   continue;   //   跳过多个空白字符 
                    state=3; 
        case   3: 
if   (space)   { 
        state=4;   
                                                        //   只取出主机名称部分 
        String   host0=host; 
        int   n; 
        n=host.indexOf( "// "); 
        if   (n!=-1)   host=host.substring(n+2); 
        n=host.indexOf( '/ '); 
        if   (n!=-1)   host=host.substring(0,n); 
                                                        //   分析可能存在的端口号 
        n=host.indexOf( ": "); 
        if   (n!=-1)   {   
port=Integer.parseInt(host.substring(n+1)); 
host=host.substring(0,n); 
        } 
        host=processHostName(host0,host,port,socket); 
        if   (parent!=null)   { 
host=parent; 
port=parentPort; 
        } 
        int   retry=CONNECT_RETRIES; 
        while   (retry--!=0)   { 
try   { 
        outbound=new   Socket(host,port); 
        break; 
}   catch   (Exception   e)   {   } 
                                                                //   等待 
Thread.sleep(CONNECT_PAUSE); 
        } 
        if   (outbound==null)   break; 
        outbound.setSoTimeout(TIMEOUT); 
        os=outbound.getOutputStream(); 
        os.write(line.getBytes()); 
        os.write( '   '); 
        os.write(host0.getBytes()); 
        os.write( '   '); 
        pipe(is,outbound.getInputStream(),os,socket.getOutputStream()); 
        break; 

host=host+(char)c; 
break; 
        } 

        } 
        catch   (IOException   e)   {   } 

        }   catch   (Exception   e)   {   } 
        finally   { 
        try   {   socket.close();}   catch   (Exception   e1)   {} 
        try   {   outbound.close();}   catch   (Exception   e2)   {} 
              } 
        } 


        void   pipe(InputStream   is0,   InputStream   is1, 
                  OutputStream   os0,     OutputStream   os1)   throws   IOException   { 
try   { 
        int   ir; 
        byte   bytes[]=new   byte[BUFSIZ]; 
        while   (true)   { 
try   { 
        if   ((ir=is0.read(bytes))> 0)   { 
os0.write(bytes,0,ir); 
if   (logging)   writeLog(bytes,0,ir,true); 
        } 
        else   if   (ir <0) 
break; 
}   catch   (InterruptedIOException   e)   {   } 
try   { 
        if   ((ir=is1.read(bytes))> 0)   { 
os1.write(bytes,0,ir); 
if   (logging)   writeLog(bytes,0,ir,false); 
        } 
        else   if   (ir <0)   
break; 
}   catch   (InterruptedIOException   e)   {   } 
        } 
}   catch   (Exception   e0)   { 
        System.out.println( "Pipe异常:   "   +   e0); 

        } 


        static   public   void   startProxy(int   port,Class   clobj)   { 
ServerSocket   ssock; 
Socket   sock; 
                try   { 
        ssock=new   ServerSocket(port); 
        while   (true)   { 
Class   []   sarg   =   new   Class[1]; 
Object   []   arg=   new   Object[1]; 
sarg[0]=Socket.class; 
try   { 
        java.lang.reflect.Constructor   cons   =   clobj.getDeclaredConstructor(sarg); 
        arg[0]=ssock.accept(); 
        cons.newInstance(arg);   //   创建HttpProxy或其派生类的实例 
}   catch   (Exception   e)   {   
        Socket   esock   =   (Socket)arg[0]; 
        try   {   esock.close();   }   catch   (Exception   ec)   {} 

        } 
}   catch   (IOException   e)   { 

        } 


        //   测试用的简单main方法 
        static   public   void   main(String   args[])   { 
System.out.println( "在端口808启动代理服务器\n "); 
HttpProxy.log=System.out; 
HttpProxy.logging=false; 
HttpProxy.startProxy(808,HttpProxy.class); 
            } 
        } 
========================= 
//   HttpProxy的简单派生类 
//   不记录主机名字 
//   在日志输出的每一行前面加上一个 '* ' 

import   java.io.*; 
import   java.net.*; 

public   class   SubHttpProxy   extends   HttpProxy   { 
        static   private   boolean   first=true; 
        public   SubHttpProxy(Socket   s)   { 
super(s); 
        } 
        public   void   writeLog(int   c,   boolean   browser)   throws   IOException   { 
if   (first)   log.write( '* '); 
first=false; 
log.write(c); 
if   (c== '\n ')   log.write( '* '); 
        } 
        public   String   processHostName(String   url,   String   host,   int   port,   Socket   sock)   { 
//   直接返回 
return   host; 
        } 
        //   测试用的简单main方法 
        static   public   void   main(String   args[])   { 
System.out.println( "在端口808启动代理服务器\n "); 
HttpProxy.log=System.out; 
HttpProxy.logging=true; 
HttpProxy.startProxy(808,SubHttpProxy.class); 
            } 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值