java实现一个简单的代理服务器

来源:互联网 发布:java 全栈开发框架 编辑:程序博客网 时间:2024/06/10 20:57

这里实现了一个基础的代理服务器,就是socket管道的跳转,但是对于应用中的代理服务器,其中必有很多东西是要注意的,考虑的,这里的代码仅仅是为了使你去了解代理服务器的一个简单流程

代理服务器类

package com.inetAddressTest.proxy;import jdk.internal.util.xml.impl.Input;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Constructor;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.text.DateFormat;import java.util.Date;import java.util.Objects;/** * Created by Administrator on 2017/5/1. */public class MyHttpProxy extends Thread {    //尝试重新连接次数    public static int CONNECT_RETRIES=5;    //尝试重连中间停顿的次数    public static int CONNECT_PAUSE=5;    //超时连接时间    public static int TIME_OUT=50;    //是否计入日志信息    public static boolean logging=false;    //日志输出位置    public static OutputStream out=null;    //设置代理服务器地址,默认为本地的8080    private static InetSocketAddress address=new InetSocketAddress("localhost",8080);    //设置父类代理服务器的地址    private static InetSocketAddress pAddress=null;    //    private Socket socket;    public static void setParentProxy(InetSocketAddress address){        pAddress=address;    }    public MyHttpProxy(Socket socket){        this.socket=socket;        start();    }    public void writeLog(int c, boolean browser) throws IOException {        out.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 proccessHostName(String url,String host,int port,Socket socket){        DateFormat df=DateFormat.getInstance();        System.out.println(df.format(new Date()+" "+url+" "+host+" "+port+" "+socket.getInetAddress()));        return host;    }    /**     * 该方法用于通道的转换     * @param in0 from     * @param in1     * @param out1 to     * @param out2     */    public void pipe(InputStream in0,InputStream in1,OutputStream out1,OutputStream out2){        int a=0;        byte[] buff=new byte[1024];        try {            while ((a=in0.read(buff))!=-1){                out1.write(buff,0,a);                writeLog(buff,0,a,true);            }        } catch (IOException e) {            //捕捉到异常时将流写回原来的流            try {                while ((a=in1.read(buff))!=-1){                    out2.write(buff,0,a);                    writeLog(buff,0,a,true);                }            } catch (IOException e1) {                e1.printStackTrace();            }        }    }    @Override    public void run() {        //被代理服务器的socket        Socket outBound=null;        String host="127.0.0.1";        int port=8900;        if(pAddress!=null){            host=pAddress.getHostName();            port=pAddress.getPort();        }        //尝试连接次数        int retry=CONNECT_RETRIES;        try {            while(true){                try {                    outBound=new Socket(host,port);                    break;                } catch (IOException e) {                    try {                        //连接失败后尝试连接等到时间                        Thread.sleep(CONNECT_PAUSE);                    } catch (InterruptedException e1) {                        e1.printStackTrace();                    }                }            }            if(outBound!=null){                outBound.setSoTimeout(TIME_OUT);                //转换通道                pipe(socket.getInputStream(),outBound.getInputStream(),outBound.getOutputStream(),socket.getOutputStream());            }        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 客服端设置代理对象     * @param address0  代理服务器地址     * @param proxy    代理类,可为HttpProxy的子类     */    public static void setProxy(InetSocketAddress address0,Class<MyHttpProxy> proxy){        if(address!=null){            address=address0;        }        ServerSocket serverSocket=null;        Socket socket=null;        try {            serverSocket=new ServerSocket(address.getPort());            while (true){                //用反射通过构造函数来得到代理类的实例                Class[] sarg=new Class[1];                Object[] oarg=new Object[1];                sarg[0]=Socket.class;                try {                    Constructor<MyHttpProxy> cons=proxy.getDeclaredConstructor(sarg);                    oarg[0]=serverSocket.accept();                    cons.newInstance(oarg);//每次接受到连接都要实例化一个对象//实际运用在是否应该考虑一下缓存问题                } catch (Exception e) {                    ((Socket)oarg[0]).close();                    e.printStackTrace();                }            }        } catch (IOException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        System.out.println("启动代理服务器");        MyHttpProxy.logging=true;        MyHttpProxy.out=System.out;        MyHttpProxy.setProxy(new InetSocketAddress("localhost",8080),MyHttpProxy.class);    }}

被代理类

package com.inetAddressTest.proxy;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket;/** * Created by Administrator on 2017/5/1. */public class SocketServerTest {    public static void main(String[] args) throws Exception{        System.out.println("启动了服务器");        ServerSocket serverSocket=new ServerSocket(8900);        while (true){            Socket socket=serverSocket.accept();            BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));            String line="";            while ((line=reader.readLine())!=null){                System.out.println(line);            }        }    }}
0 0
原创粉丝点击