1

Java で非常に単純な、最小限のスレッド化された HTTP プロキシ サーバーをコーディングしようとしましたが、かなりの進歩を遂げました。

  1. クライアントがサーバーに接続し、クライアントへの入力ストリームと出力ストリームが作成されます

  2. ターゲット URL は GET 要求から抽出されます

  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 に答える