java写的http代理服务器

原创 2004年09月08日 18:02:00

为了通过客户的机子代理上外网,不能用ccproxy只好自己写了一个:

so simple , so easy ! But all my colleagues  are so surprised . So , I am  very

surprised !

首先需要一个线程缓冲池,和数据库连接池很不一样,两个类:

import java.util.*;


/**
 * 描述:
 *
 * @author $张忠强$
 * @version $Revision$
 */
public class ThreadPool {

    protected Thread []       threads     = null;
    Collection                assignments = new ArrayList(3); //初始为3个元素,动态增减。
    protected Done            done        = new Done();
    private static ThreadPool pool        = null;

    //连接池配置-应从配置文件中读取
    static int threadSize = 10;

    //
    public static ThreadPool getInstance() {

        if (pool == null) {

            pool = new ThreadPool(threadSize);
        }

        return pool;
    }

    /**
     * 构造一个新的 ThreadPool 对象.
     *
     * @param size 描述:
     */
    private ThreadPool(int size) {

        threads = new WorkerThread[ size ];

        for (int i = 0; i < threads.length; i++) {

            threads [ i ] = new WorkerThread(this);
            threads [ i ].start ();
        }
    }

    /**
     * 描述:注册要执行的任务
     *
     * @param r 描述:
     */
    public synchronized void assign(Runnable r) {

        done.workerBegin ();
        assignments.add (r);
        notify ();
    }

    /**
     * 描述:
     *
     * @return 描述:
     */
    public synchronized Runnable getAssignment() {

        try {

            while (!assignments.iterator ().hasNext ())
                wait ();

            Runnable r = (Runnable) assignments.iterator ().next ();
            assignments.remove (r);

            return r;
        }
        catch (InterruptedException e) {

            done.workerEnd ();

            return null;
        }
    }

    /**
     * 描述:
     */
    public void complete() {

        done.waitBegin ();
        done.waitDone ();
    }

    /**
     * 描述:
     */
    protected void finalize() {

        done.reset ();

        for (int i = 0; i < threads.length; i++) {

            threads [ i ].interrupt ();
            done.workerBegin ();

            //threads[i].destroy();
        }

        done.waitDone ();
    }
}


/**
 * 描述:执行任务的线程对象
 *
 * @author $author$
 * @version $Revision$
 */
class WorkerThread extends Thread {

    public boolean    busy;
    public ThreadPool owner;

    /**
     * 构造一个新的 WorkerThread 对象,并关联到池.
     *
     * @param o 描述:
     */
    WorkerThread(ThreadPool o) {

        owner = o;
    }

    /**
     * 描述:实现接口
     */
    public void run() {

        Runnable target = null;

        do {

            target = owner.getAssignment ();

            if (target != null) {

                target.run ();
                owner.done.workerEnd ();
            }
        }
        while (target != null);
    }
}

 

/**
 * 描述:
 *
 * @author $张忠强$
 * @version $Revision$
 */
public class Done {

    private int     activeThreads = 0;
    private boolean started = false;

    /**
     * 描述:
     */
    public synchronized void waitDone() {

        try {

            while (activeThreads > 0) {

                wait ();
            }
        }
        catch (InterruptedException e) {

        }
    }

    /**
     * 描述:
     */
    public synchronized void waitBegin() {

        try {

            while (!started) {

                wait ();
            }
        }
        catch (InterruptedException e) {

        }
    }

    /**
     * 描述:
     */
    public synchronized void workerBegin() {

        activeThreads++;
        started = true;
        notify ();
    }

    /**
     * 描述:
     */
    public synchronized void workerEnd() {

        activeThreads--;
        notify ();
    }

    /**
     * 描述:
     */
    public synchronized void reset() {

        activeThreads = 0;
    }
}

服务线程:

import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;

import java.net.Socket;


/**
 * 描述:
 *
 * @author $张忠强$
 * @version $Revision$
 */
public class DataService implements Runnable {

    int     CONNECT_RETRIES = 5;
    int     CONNECT_PAUSE = 5;
    int     TIMEOUT       = 50; //socket超时设置
    int     BUFSIZ        = 1024 * 5; //缓冲区
    boolean loging        = false; //是否输出日志信息

    //和此线程关联的Socket,用于和客户端交换数据
    Socket socket;

    //输出日志
    public void log(String log) {

        if (loging) {

            System.out.println (log);
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param s 描述:
     */
    public DataService(Socket s) {

        socket = s;
    }

    //对请求的每一个图元进行服务的线程
    public void run() {

        String line;
        String host;
        int    port     = 80; //默认
        Socket outbound = null;

        try {

            socket.setSoTimeout (TIMEOUT);

            InputStream  is = socket.getInputStream ();
            OutputStream os = null;

            // 获取请求行的内容
            line     = "";
            host     = "";

            int     state = 0;
            boolean space;

            while (true) {

                int c = is.read ();

                if (c == -1) {

                    break;
                }

                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);
                            }

                            //如果存在上级代理,则不用进行以上操作,直接和代理通讯
                            
                            int retry = CONNECT_RETRIES;

                            //尝试连接远程目标,CONNECT_RETRIES次
                            while (retry-- != 0) {

                                try {

                                    outbound = new Socket(host, port);

                                    break;
                                }
                                catch (Exception e) {

                                    //System.out.println ("重试...");
                                }

                                // 等待
                                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; //跳出case 3
                        }

                        host = host + (char) c;

                        break;

                    //-------------------------------------------------------------
                }
            }
        }
        catch (Exception e) {

        }
        finally {

            try {

                socket.close ();
            }
            catch (Exception e1) {

            }

            try {

                outbound.close ();
            }
            catch (Exception e2) {

            }
        }
    }

    /**
     * 描述:数据传送桥
     *
     * @param is0 描述:读取客户的请求信息
     * @param is1 描述:读取远程服务器返回数据
     * @param os0 描述:向远程服务器写入请求信息
     * @param os1 描述:向客户端写入服务器返回数据
     */
    void pipe(InputStream is0, InputStream is1, OutputStream os0,
        OutputStream os1) {

        try {

            int     ir;
            byte [] bytes = new byte[ BUFSIZ ];

            while (true) {

                try {

                    if ((ir = is0.read (bytes)) > 0) {

                        os0.write (bytes, 0, ir);

                        //System.out.println (new String(bytes).trim ());
                    }
                    else if (ir < 0) {

                        break;
                    }
                }
                catch (InterruptedIOException e) {

                }

                try {

                    if ((ir = is1.read (bytes)) > 0) {

                        os1.write (bytes, 0, ir);
                    }
                    else if (ir < 0) {

                        break;
                    }
                }
                catch (InterruptedIOException e) {

                }
            }
        }
        catch (Exception e0) {

            //System.out.println ("Pipe异常: " + e0);
        }
    }
}

主类:

import java.io.*;

import java.net.*;


/**
 * 描述:代理服务器类
 *
 * @author $张忠强$
 * @version $1.0$
 */
public class HttpProxy {

    /*/上级代理服务器地址和端口
       private static String parent     = null;
       private static int    parentPort = -1;
       /**
     * 描述:设置上级代理地址和端口,可选方法
     *
     * @param name 描述:
     * @param pport 描述:
     */
    /*
       public static void setParentProxy(String name, int pport) {
           parent         = name;
           parentPort     = pport;
       }*/

    /**
     * 描述:开启代理服务
     *
     * @param port 描述:
     */
    public static void startProxy(int port) {

        ServerSocket ssock = null;
        ThreadPool   pool = ThreadPool.getInstance ();

        try {

            ssock = new ServerSocket(port);
            System.out.println ("在端口25启动代理服务器/n");

            //浏览器对同一页面上的不同图元采用不同的线程进行请求的
            //所以用不同的线程进行服务
            //一个页面使用的线程数和其图元数一致
            //所以采用线程池是必要的
            while (true) {

                Socket tmp = ssock.accept ();

                pool.assign (new DataService(tmp));
            }
        }
        catch (IOException e) {

            e.printStackTrace ();
        }
        finally {

            pool.complete ();

            if (ssock != null) {

                try {

                    ssock.close ();
                }
                catch (Exception e) {

                }
            }
        }
    }

    // 测试用的简单main方法
    public static void main(String [] args) {

        HttpProxy.startProxy (25);
    }
}

可以将其植入servlet中,达到真正的隐藏。。。


编写了一个简单的http代理服务器

单位一直使用ccproxy,破解版的。 不爽,于是,自己编写了一个简单的http代理服务器。 当然,功能还是和标题一样,简单的。 希望有高手一起开发。 争取日后国内一说起写代理服务器,就首先想...
  • lifan_3a
  • lifan_3a
  • 2014年07月06日 02:21
  • 1263

兼容https和http协议的java代理服务器代码

最近做的一个http代理小程序,同时支持http和http。 1、获取http代理请求的头部信息,区分https还是http,做不同的处理 /** * 解析头部信息 * */ public fi...
  • qq631431929
  • qq631431929
  • 2015年10月18日 23:42
  • 11813

使用Java Nio异步套接字实现一个简单的http代理服务器

使用NIO实现的异步简单HTTP代理服务器,不支持HTTPS代理。文件名:Main.javapackage jHttpProxy;import java.io.IOException; import ...
  • chenlei1998
  • chenlei1998
  • 2017年03月12日 15:57
  • 403

如何用Java写一个简单的代理Web服务器

What is Proxy Web Server 1.Receive HTTP request from A2.Transmit request to real server3.Receive re...
  • u010592415
  • u010592415
  • 2014年06月30日 11:13
  • 1292

计算机网络--http代理服务器的设计与实现

一、Socket编程的客户端和服务端的主要步骤: Java Socket编程:对于http传输协议 客户端: 1、创建新的socket,绑定服务器host和端口号 2、Socket创建成功后获得相应的...
  • u011955072
  • u011955072
  • 2015年06月05日 00:10
  • 4904

HTTP代理服务器的实现

一.套接字编程 API函数介绍 SOCKET accept( SOCKET s , struct sockaddr_in FAR * addr ,int Far *addlen ) ;  函数说...
  • bobopeng
  • bobopeng
  • 2014年02月13日 14:51
  • 11543

Socket编程--自己动手的HTTP代理服务器

自己动手实现简单的HTTP代理服务器
  • idevede
  • idevede
  • 2017年02月02日 11:35
  • 2439

windows平台HTTP代理服务器搭建(CCproxy)

windows平台HTTP代理服务器搭建(CCproxy)
  • Moolight_shadow
  • Moolight_shadow
  • 2015年06月06日 19:41
  • 14765

java代理服务器设置

一、设置系统代理 方法如下: java -Dhttp.proxyHost=192.168.254.254  -Dhttp.proxyPort=9000  com.domain.Program 或...
  • xiaomin1991222
  • xiaomin1991222
  • 2016年03月10日 16:05
  • 2623

搭建自己的http代理服务器

由于在某些特定场景下,我们的外网访问会受到限制,如果有一些访问需求的话就需要一个代理作为中转了。 首先需要一台机器作为中转的服务器,这时候当然要去阿里云买一台啦。操作系统一定要选Linux,我使用的是...
  • fylfyl2
  • fylfyl2
  • 2015年09月16日 16:56
  • 21884
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java写的http代理服务器
举报原因:
原因补充:

(最多只允许输入30个字)