1

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

  1. 客户端连接到服务器,对客户端进行输入和输出流

  2. 从 GET 请求中提取目标 URL

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

现在我明白我需要发送来自服务器输入流的数据并将其转发到客户端输出流,但是如何准确地做到这一点让我无法理解。我在输入和输出流方面的经验的扩展一直是发送单个字符串,而且我对这些流的工作原理还不太清楚。

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

这是我的代码:

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--------------------------------------------------------------------------
4

1 回答 1

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

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

于 2013-04-22T01:45:53.287 回答