与代理的输入/输出流混淆

时间:2013-04-22 01:15:20

标签: java proxy stream

尝试用Java编写一个非常简单,简单的线程HTTP代理服务器 我取得了很好的进展:

  1. 客户端连接到服务器,输入和输出 流向客户端的流程

  2. 目标网址是从GET请求中提取的

  3. 与目标Web服务器建立连接,并建立输入流

  4. 现在我明白我需要发送来自服务器输入流的数据并转发 它到客户端输出流,但如何正确地做到这一点逃避了我。我的经验延伸 输入和输出流一直在发送单个字符串,而且我还不太稳固 了解这些流的确切运作方式。

    我是否应该将输入流中的所有数据读入文件,然后写入输出流?有更优雅的解决方案吗?

    这是我的代码:

    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public class Proxy {
    
    /////////////////////////////////////
    public static void go(){
    
    int incomingport = 50000;
    ServerSocket myproxysocket = null;
    
    try{
    myproxysocket = new ServerSocket(incomingport);
    while(true){
    System.out.println("HTTP Java Proxy Server");
    System.out.println();
    System.out.println("Listening on port 50000...Press CTRL+C to exit");
    System.out.println();
    Socket client = myproxysocket.accept();
    Thread t = new Thread(new ClientHandler(client));
    t.start();
    }//end while
    }//end try
    
    catch(Exception E){
    E.printStackTrace();    
    }
    }//end method go()
    
    ///////////////////////////////////
    public static void main(String args[]) {
    
    Proxy myserver =  new Proxy();
    myserver.go();
    
    }//end main
    }//end class proxy
    
    
    /////////////////////////////////////////////////////////////////////////////////////
    class ClientHandler implements Runnable{
    
    private final DataInputStream clientin;
    private final DataOutputStream clientout;
    private final Socket clientSocket;
    
    
    //constructor----------------
    public ClientHandler(Socket incomingSocket) throws IOException{
    
    clientSocket = incomingSocket; 
    clientin = new DataInputStream(incomingSocket.getInputStream());
    clientout = new DataOutputStream(incomingSocket.getOutputStream());
    
    
    }//--------------------------
    
    ////////////////////
    public void run(){
    try{
    
    //Get URL from client
    String getrequestline = clientin.readLine();
    String targetURL = null;
    String clientIP = null;
    StringTokenizer st = new StringTokenizer(getrequestline);
    st.nextToken();
    targetURL = st.nextToken();
    clientIP = clientSocket.getRemoteSocketAddress().toString();
    System.out.println();
    System.out.println("IP: " + clientIP);
    System.out.println("Requested URL: " + targetURL);
    System.out.println();
    
    //connect to target URL
    URL url = new URL(targetURL);
    URLConnection targetconnection = url.openConnection();
    targetconnection.setDoInput(true);
    targetconnection.setDoOutput(false);
    
    
    InputStream is = targetconnection.getInputStream();
    
    //How do I read in from is and write out to clientout?
    
    //clientout.write(???????)
    
    }//try
    catch(Exception E){
     E.printStackTrace();
    }//catch
    finally{
    try{clientSocket.close();}
    catch(Exception ee){}
    }//finally
    }//end run----------
    
    }//end CLASS--------------------------------------------------------------------------
    

1 个答案:

答案 0 :(得分:1)

中有一个非常简洁的实用工具类
org.apache.commons.io.IOUtils

来自commons-io包的那些。如果可以,请使用它。否则,一个简单的方法(不使用任何NIO的东西)就是这样:

public static void copy(InputStream is, OutputStream os) throws IOException {
    byte[] buff = new byte[1024*1024];
    int a = 0;
    while((a = is.read(buff)) > -1) {

        // a is the number of bytes ACTUALLY read, so 
        // when we write, that's the number of bytes to write
        os.write(buff,0,a);
    }
    os.flush();
}

并且像往常一样,不要忘记冲洗。