Java 与代理的输入/输出流混淆
试图用Java编写一个非常简单、简单的线程HTTP代理服务器,以及 我取得了很好的进步:Java 与代理的输入/输出流混淆,java,proxy,stream,Java,Proxy,Stream,试图用Java编写一个非常简单、简单的线程HTTP代理服务器,以及 我取得了很好的进步: 客户端连接到服务器、输入和输出 流到客户端 目标URL是从GET请求中提取的 与目标web服务器建立连接,并建立inputstream 现在我知道我需要发送来自服务器inputstream的数据并转发 它可以发送到客户端outputstream,但我不知道如何准确地执行此操作。我经验的扩展 对于输入和输出流,一直在发送单个字符串,我没有一个固定的 了解这些流是如何工作的 我是否应该将输入流中的所有数据读取到
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--------------------------------------------------------------------------
中有一个非常整洁的实用程序类
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();
}
和往常一样,不要忘记刷新。中有一个非常整洁的实用程序类
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();
}
和往常一样,别忘了冲洗。谢谢!。如果buff是一个字节数组,那么两个流之间到底发送了什么?它不是HTML吗?例如,当JSP在服务器上生成HTML时,它可以设置它的字符编码(或使用默认值)。然后使用此字符编码转换文本(可能包含多字节字符,如“你好") 在HTTP报头中,服务器还告诉客户端它使用的编码,以便客户端可以将其转换回实际字符。在这两者之间,它只是一堆字节,很像“.getBytes”(“utf-8”);将为您提供一个6字节的数组,但是”你好.getBytes(“utf-8”)将为您提供一个6字节的数组。你好 中文中的“hello”是2个字符,实际上(在utf-8中)转换为6个字节。因为您的代理不必知道实际的字符(它不必显示它们),您可以只复制原始字节。如果您想了解字符,您必须读取标题,找出字符编码,解码字节,然后再次执行相同的操作(在另一侧发送头,然后使用相同的字符编码将字符编码为字节。还有一个问题:用于连接到代理的端口不断从50000上升,即使在重新启动代理后也是如此。目前已达到62000左右的端口。是否需要关闭套接字?如果重新启动代理,即当VM ex如果buff是一个字节数组,那么两个流之间到底发送了什么?它不是HTML吗?例如,当JSP在服务器上生成HTML时,它可以设置其字符编码(或使用默认值)。然后使用此字符编码转换文本(可能包含多字节字符,例如“你好") 在HTTP报头中,服务器还告诉客户端它使用的编码,以便客户端可以将其转换回实际字符。在这两者之间,它只是一堆字节,很像“.getBytes”(“utf-8”);将为您提供一个6字节的数组,但是”你好.getBytes(“utf-8”)将为您提供一个6字节的数组。你好 中文中的“hello”是2个字符,实际上(在utf-8中)转换为6个字节。因为您的代理不必知道实际的字符(它不必显示它们),您可以只复制原始字节。如果您想了解字符,您必须读取标题,找出字符编码,解码字节,然后再次执行相同的操作(在另一侧发送头,然后使用相同的字符编码将字符编码为字节。还有一个问题:用于连接到代理的端口不断从50000上升,即使在重新启动代理后也是如此。目前已达到62000左右的端口。是否需要关闭套接字?如果重新启动代理,即当VM ex它的,这些应该被自动释放。