2 baidu 24550657 baidu_24550657 于 2014.12.16 10:35 提问

JAVA代理服务器,用浏览器打开的时候显示的网页信息总是不全,有时候显示不出来,求大神帮我看看

package work;
import java.io.*;
import java.net.*;

public class MMProxy extends Thread {

static public int CONNECT_RETRIES = 5;    //尝试与目标主机连接次数  
static public int CONNECT_PAUSE = 5;  //每次建立连接的间隔时间  
static public int TIME_OUT = 50;//每次尝试连接的最大时间
static public int BUFSIZ = 4096;  //缓冲区最大字节数
protected static Socket csocket;//与客户端相连的socket

public MMProxy(Socket cs) {
    csocket = cs;
    start();
}

public void run() {
    String buffer = "";//请求头
    String host = "";//目标主机IP地址
    String URL = "";//请求URL
    int port = 8080;
    Socket ssocket = null;//套接字
    InputStream cinput = null, sinput = null;//cinput为客户输入流,sinput为服务器输入流
    OutputStream coutput = null, soutput = null;//coutput为客户输出流,soutput服务器输出流
    try {//服务器监听客户端的套接字
        csocket.setSoTimeout(TIME_OUT);//超过了50则返回一个异常
        cinput = csocket.getInputStream();
        coutput = csocket.getOutputStream();
        while (true) {//服务端读来自客户端的输入流
            int c = cinput.read();
            if (c == -1) {
                break;//-1为结尾标志
            }
            if (c == '\r' || c == '\n') {
                break;
            }
            buffer = buffer + (char) c;//读取第一行的数据
        }
        URL = getRequestURL(buffer);
        int n;
        n = URL.indexOf("//");//找到URL中“//”的位置
        if (n != -1) {
            host = URL.substring(n + 2);
        }
        n = host.indexOf("/");
        if (n != -1) {
            host = host.substring(0, n);//抽取host
        }
        n = host.indexOf(":");//分析端口号
        if (n != -1) {
            port = Integer.parseInt(host.substring(n + 1));
            host = host.substring(0, n);
        }
        int tetry = CONNECT_RETRIES;
        while (tetry-- != 0) {//尝试与目标主机建立连接
            try {
                ssocket = new Socket(host, port);
                break;
            } catch (Exception e) {
            }
            Thread.sleep(CONNECT_PAUSE);//等待
        }
        if (ssocket != null) {
            ssocket.setSoTimeout(TIME_OUT);
            sinput = ssocket.getInputStream();
            soutput = ssocket.getOutputStream();
            soutput.write(buffer.getBytes());
            System.out.println(buffer);
            pipe(cinput, sinput, coutput, soutput);//pipe在两个socket之间进行读写
            //SocketAddress address=new InetSocketAddress("192.168.0.1",8080);
            //Proxy proxy=new Proxy(Proxy.Type.HTTP,address);
            //URL pageUrl=new URL(host);
            //HttpURLConnection httpUrlConn = (HttpURLConnection)pageUrl.openConnection(proxy);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            csocket.close();
            cinput.close();
            coutput.close();
        } catch (Exception e1) {
            System.out.println("\nClient Socket Closed Exception:");
            e1.printStackTrace();
        }
        try {
            ssocket.close();
            sinput.close();
            soutput.close();
        } catch (Exception e2) {
            System.out.println("\nServer Socket Closed Exception:");
            e2.printStackTrace();
        }
    }
}

public String getRequestURL(String buffer) {//读取URL第一行
    String[] tokens = buffer.split(" ");
    String URL = "";
    for (int i = 0; i < tokens.length; i++) {
        if (tokens[i].startsWith("http://")) {
            URL = tokens[i];
            break;
        }
    }
    return URL;
}

public void pipe(InputStream cinput, InputStream sinput, OutputStream coutput, OutputStream soutput) {//主机与代理服务器的数据通道
    try {
        int length;
        byte bytes[] = new byte[BUFSIZ];
        while (true) {
            try {
                while ((length = cinput.read(bytes)) > 0) {
                    soutput.write(bytes, 0, length);
                }
                //else if(length<0)break;
            } catch (SocketTimeoutException e) {
            } catch (InterruptedIOException e) {
                System.out.println("\nRequest Exception:");
                e.printStackTrace();
            }
            try {
                while ((length = sinput.read(bytes)) > 0) {
                    coutput.write(bytes, 0, length);
                }
                 //else if (length<0) ;  
                //    break;  
            } catch (SocketTimeoutException e) {
            } catch (InterruptedIOException e) {
                System.out.println("\nResponse Exception:");
                e.printStackTrace();
            }
        }
    } catch (Exception e0) {
        System.out.println("Pipe异常: " + e0);
    }
}

public static void main(String args[]) {
    try {
        ServerSocket ssock = new ServerSocket(8080);//监听端口8080
        while (true) {
            Socket lsocket = ssock.accept();//使sever端处于等待状态,直到接受来自客户端的请求,并返回一个与客户通信的socket对象
            new MMProxy(lsocket);//.start();//从请求中取出连接,这时已经建立好了与客户端的双向连接
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

2个回答

caozhy
caozhy   Ds   Rxr 2014.12.16 10:38

用socket写一个支持http1.1标准的web proxy不可能只有这么点代码,这代码明显不靠谱。它勉强能工作就不错了。
你可以用fiddler看下http报文,是什么不支持。

yangyanggoods
yangyanggoods   2014.12.20 12:18

我只想知道你这个“代理服务器”是如何获得请求的……而且HTTP请求头根本就不是http://host/这样的格式啊

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!