尝试用Java编写一个非常简单,简单的线程HTTP代理服务器 我取得了很好的进展:
客户端连接到服务器,输入和输出 流向客户端的流程
目标网址是从GET请求中提取的
与目标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--------------------------------------------------------------------------
答案 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();
}
并且像往常一样,不要忘记冲洗。